Last Updated: 2026-04-28
Longbow provides an integrated suite of search capabilities, from low-latency vector similarity to complex relational filtering and graph-based retrieval.
| Mode | Description | Python SDK |
|---|---|---|
| Dense | HNSW-based vector similarity | client.search() |
| Sparse | BM25/Keyword matching | Built-in |
| Filtered | Metadata filtering | filters= parameter |
| Hybrid | RRF-fused dense + sparse | client.search(alpha=0.5) |
| ByID | Instant specific vector retrieval | client.search_by_id() |
| Temporal | Versioned time-travel queries | client.temporal_search() |
| Geo-Spatial | Radius/bounding box search | client.geo_search() |
| GraphRAG | Knowledge graph spreading | client.recommend() |
| Learned Index | Automatic index selection | Auto-enabled |
| TurboQuant | Compressed vector search | vector_type="turboquant" |
HNSW-based vector similarity with sub-millisecond latency.
from longbow import LongbowClient
client = LongbowClient(uri="grpc://localhost:3000")
client.connect()
# Basic vector search
results = client.search(
dataset="documents",
vector=[0.1, 0.2, 0.3, ...], # Query vector
k=10 # Return top 10
)
# Returns DataFrame with: id, text, distance columns| Metric | Formula | Best For |
|---|---|---|
| Euclidean (L2) | √(Σ(a[i] - b[i])²) |
Image search |
| Cosine Distance | 1.0 - (dot(a,b) / (||a||*||b||)) |
Text embeddings |
| Dot Product | -(Σ(a[i] * b[i])) |
MIPS, recommendations |
For billion-scale datasets:
client.create_namespace(
name="billion_scale",
dims=768,
data_type="opq", # Optimized Product Quantization
nlist=1024, # IVF clusters
nprobe=64 # Clusters to search
)Traditional full-text retrieval using inverted index.
Algorithm: BM25 with configurable
Use Case: Exact keyword matching where semantic embeddings might be too "fuzzy".
Combines Dense and Sparse retrieval.
results = client.search(
dataset="documents",
vector=[0.1, 0.2, ...],
text_query="search terms", # Combine with BM25
alpha=0.7, # 1.0 = dense, 0.0 = sparse
k=10
)Metadata filtering using post-filtering.
results = client.search(
dataset="documents",
vector=[0.1, 0.2, ...],
filters=[
{"field": "category", "op": "eq", "value": "tech"},
{"field": "priority", "op": "gte", "value": 5},
],
k=10
)Operators: eq, neq, gt, gte, lt, lte, in, like
O(1) instant retrieval of specific vectors.
# Find neighbors of known vector
results = client.search_by_id(
dataset="documents",
id=12345,
k=10 # Get 10 nearest neighbors
)
# Get single vector
vector = client.get_vector(
dataset="documents",
id=12345
)Versioned discovery via snapshots.
# As-Of search (state at specific time)
results = client.temporal_search(
dataset="documents",
search_type="as_of",
timestamp=1700050000000000000, # Unix nanoseconds
k=10
)
# Range search (time window)
results = client.temporal_search(
dataset="documents",
search_type="range",
start_time=1700000000000000000,
end_time=1700100000000000000,
k=10
)
# Sliding window (last N items)
results = client.temporal_search(
dataset="documents",
search_type="sliding_window",
window_size=100,
k=10
)
# Sliding window by duration
results = client.temporal_search(
dataset="documents",
search_type="sliding_window_time",
duration="1h", # "30m", "2h", "1d"
k=10
)
# Version history
versions = client.temporal_version_history(
dataset="documents",
vector_id=12345
)Location-aware search using Quadtree index.
# Radius search (Haversine distance)
results = client.geo_search(
dataset="locations",
center={"lat": 37.7749, "lon": -122.4194},
radius_km=10,
search_type="radius",
k=10
)
# Bounding box search
results = client.geo_search(
dataset="locations",
box={"min_lat": 37.7, "max_lat": 37.8, "min_lon": -122.5, "max_lon": -122.4},
search_type="box",
k=10
)
# Hybrid (vector + geo)
results = client.geo_search(
dataset="locations",
center={"lat": 37.7749, "lon": -122.4194},
radius_km=5,
vector=[0.1, 0.2, ...], # Combine with semantic search
search_type="hybrid",
k=10
)Dual-path: Spreading Activation + Knowledge Graph triples.
# Hybrid search with graph re-ranking
results = client.search(
dataset="documents",
vector=[0.1, 0.2, ...],
alpha=0.7, # Graph weight (1.0 = full graph, 0.0 = pure vector)
depth=2, # Graph traversal depth
k=10
)# Add edges
client.add_edge(
dataset="knowledge",
subject=1,
predicate="knows",
object=2,
weight=1.0
)
# Recommend (hybrid vector-graph)
results = client.recommend(
dataset="documents",
seed_ids=["doc_1", "doc_2"],
alpha=0.5, # Balance vector vs graph
max_hops=2,
k=10
)
# Traverse graph
results = client.traverse(
dataset="knowledge",
start=1,
max_hops=2,
decay=0.5
)
# PageRank centrality
scores = client.calculate_pagerank(dataset="knowledge")
# Community detection
communities = client.detect_communities(dataset="knowledge")Two-stage vector compression achieving 4-64x storage reduction.
# Create TurboQuant dataset
client.create_namespace(
name="compressed",
dims=768,
data_type="turboquant", # or "tq"
turboquant_bits=4 # 2, 4, or 8 bits
)
# Search works the same
results = client.search(
dataset="compressed",
vector=[0.1, 0.2, ...],
k=10
)| Bits | Compression | Typical Use |
|---|---|---|
| 2-bit | 16x | Archival |
| 4-bit | 8x | Standard |
| 8-bit | 4x | High recall |
Automatic index selection using k-NN classifier.
11-dimensional features including:
DatasetSize(Most discriminating)QueryComplexityAvgVectorNormIsFiltered/IsHybrid
System learns optimal weights over time via Fisher Linear Discriminant (LDA).
Scatter-gather search across multiple Longbow nodes.
Query → Local HNSW Search → Scatter to Peers → Gather Raw Vectors → Global Sort → Merge (RRF) → Top-K
For Hybrid searches, the GlobalSearchCoordinator gathers the full top-K raw Dense and Sparse lists globally before applying Global Reciprocal Rank Fusion (RRF) to ensure mathematical correctness of the rank denominators.
# Automatic global search when peer nodes available
results = client.search(
dataset="documents",
vector=[0.1, 0.2, ...],
k=10
# If cluster peers exist, automatically scatter-gathers
)Each vector has a global ID across the cluster:
- GlobalID: Unique across all nodes (node_id << 32 | local_id)
- LocalID: Unique within single node
# Force local-only search (skip scatter-gather)
results = client.search(
dataset="documents",
vector=[0.1, 0.2, ...],
k=10,
local_only=True # Skip cluster peers
)
# Specify specific nodes
results = client.search(
dataset="documents",
vector=[0.1, 0.2, ...],
k=10,
nodes=["node-1", "node-2"] # Specific peers only
)| Metric | Description |
|---|---|
longbow_global_search_fanout_size |
Peers contacted per search |
longbow_global_search_partial_failures |
Failed peer queries |
longbow_global_search_duration_seconds |
Scatter-gather latency |
longbow_gossip_active_members |
Healthy cluster nodes |
longbow_global_rrf_latency_seconds |
Latency of global reciprocal rank fusion |
longbow_global_rrf_payload_bytes |
Payload elements passed to global RRF |
# Benchmark distributed search
python3 scripts/unified_benchmark.py \
--mode cluster \
--dims 768 \
--counts 10000 \
--peers 3- Trip Conditions: 10 consecutive failures
- Cooldown: 30-second reset
| Metric | Description |
|---|---|
longbow_search_ops_total |
Throughput per mode |
longbow_search_duration_seconds |
Latency P50/P95/P99 |
longbow_vector_search_latency_seconds |
Search latency histogram |
longbow_turboquant_search_total |
TurboQuant search count |
longbow_learned_index_adaptations_total |
Adaptive index switches |
# Run benchmark suite
python3 scripts/unified_benchmark.py \
--mode dense,hybrid,filtered,byid,temporal,geo,graphrag,turboquant \
--dims 768 \
--counts 10000Note
For complete GraphRAG documentation, see graphrag.md.