Skip to content

Commit 5b098ca

Browse files
committed
fix: handle single-row batch search in ShardedIndex merge path (#22)
Treat batch_size=1 queries as single queries so usearch's 1D Matches return type is handled correctly by all merge/filter/truncate paths.
1 parent b3a4e7a commit 5b098ca

5 files changed

Lines changed: 267 additions & 258 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.6.1] - 2026-03-10
11+
12+
### Fixed
13+
14+
- `ShardedIndex.search()` raises `AxisError` when merging results from view and active shards
15+
with a single-row 2D query of shape `(1, ndim)` ([#22](https://github.com/iscc/iscc-usearch/issues/22))
16+
1017
## [0.6.0] - 2026-02-22
1118

1219
### Added

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "iscc-usearch"
3-
version = "0.5.0"
3+
version = "0.6.1"
44
description = "Scalable approximate nearest neighbor search for variable-length binary bit-vectors using NPHD metric."
55
readme = "README.md"
66
license = "Apache-2.0"

src/iscc_usearch/sharded.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,10 @@ def search(
731731
raise ValueError("`count` must be >= 1")
732732

733733
vectors = np.asarray(vectors)
734-
is_single = vectors.ndim == 1
734+
# Treat batch_size=1 as single query — usearch returns 1D Matches
735+
# for single-row batches, so all downstream merge/filter/truncate
736+
# logic must use the single-query path (see issue #22).
737+
is_single = vectors.ndim == 1 or (vectors.ndim == 2 and vectors.shape[0] == 1)
735738

736739
view_results: Matches | BatchMatches | None = None
737740
active_results: Matches | BatchMatches | None = None
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""Test ShardedIndex search with single-row 2D batch input.
2+
3+
Regression test for GitHub issue #22: AxisError when merging results from
4+
both view shards and active shard with a (1, ndim) shaped query vector.
5+
"""
6+
7+
import numpy as np
8+
9+
from iscc_usearch.sharded import ShardedIndex
10+
11+
12+
def test_search_single_row_batch_with_merge(tmp_path):
13+
"""Search with shape (1, ndim) when both view and active shards have data."""
14+
ndim = 64
15+
index = ShardedIndex(ndim=ndim, path=tmp_path, shard_size=4096)
16+
17+
# Add vectors and save to create view shards
18+
vectors = np.random.rand(50, ndim).astype(np.float32)
19+
index.add(list(range(50)), vectors)
20+
index.save()
21+
22+
# Add more to active shard so merge path is triggered
23+
extra = np.random.rand(10, ndim).astype(np.float32)
24+
index.add(list(range(50, 60)), extra)
25+
26+
# Verify both view and active shards have data
27+
assert index._view_shards is not None and len(index._view_shards) > 0
28+
assert index._active_shard is not None and len(index._active_shard) > 0
29+
30+
# Single-row 2D input — this triggers the bug
31+
query = np.random.rand(1, ndim).astype(np.float32)
32+
result = index.search(query, count=5)
33+
34+
assert len(result.keys) <= 5
35+
assert len(result.distances) <= 5

0 commit comments

Comments
 (0)