FANNG1 opened a new issue, #67117:
URL: https://github.com/apache/doris/issues/67117
## Problem
Doris may fall back to Flat Search even when a metric-compatible Lance
vector index exists on the queried column.
Lance permits multiple named logical vector indexes on the same vector
column. For example:
```text
vec_l2 column=vector, metric=L2
vec_cosine column=vector, metric=COSINE
```
For a `vector_search()` request with `metric=cosine`, Doris should be able
to select `vec_cosine`. Currently, if `vec_l2` appears first in the index
metadata returned to the FE, Doris selects all segments belonging to `vec_l2`,
checks their metric afterwards, and falls back to fragment-based search when
the metric does not match. It does not continue looking for `vec_cosine`.
The query result remains correct because Lance executes Flat Search with the
requested metric, but the available ANN index is silently missed. Query latency
and resource usage can therefore depend on index metadata ordering.
## Current implementation
`LanceScanNode.selectIndexSegments()` first locks onto the first logical
index covering the vector field:
```java
if (selectedIndexName == null) {
selectedIndexName = segment.getIndexName();
}
if (selectedIndexName.equals(segment.getIndexName())) {
selectedSegments.add(segment);
}
```
Only after that selection does `createIndexSegmentSplits()` call
`metricMatches()`:
```java
List<LanceIndexSegmentInfo> matchingSegments = selectIndexSegments(
metadata.getIndexSegments(), vectorFieldId);
if (matchingSegments.isEmpty() || !metricMatches(vectorSearchParam,
matchingSegments)) {
return Optional.empty();
}
```
Relevant code:
-
`fe/fe-core/src/main/java/org/apache/doris/datasource/lance/source/LanceScanNode.java`
-
`fe/fe-core/src/main/java/org/apache/doris/datasource/lance/LanceMetadataLoader.java`
The FE already loads the information needed to make a metric-aware decision:
- logical index name
- indexed field IDs
- physical segment UUIDs
- index metric
- fragment coverage
This is not a Lance index-format limitation. Doris can select a logical
index by sending that index's physical segment UUIDs to the BE; no new Lance
`index_name` scanner parameter is required for automatic metric-aware selection.
## Expected behavior
When `use_index=true`, Doris should:
1. Group physical index segments by logical index name.
2. Keep logical indexes covering the requested vector field.
3. Resolve the requested metric using Doris semantics (`L2` when the query
metric is omitted or `DEFAULT`).
4. Select a logical index whose segments use the requested metric.
5. Route only that logical index's segment UUIDs to the BE.
6. Fall back to Flat Search only when no compatible logical index can be
planned safely.
If more than one logical index matches both the field and metric, Doris
should either define a deterministic documented policy or later expose an
optional `index_name` query property. Explicit user selection is a separate
enhancement; it is not required to fix the missed compatible-index case.
Legacy index metadata without a metric or fragment bitmap should continue to
use the existing conservative fallback unless a safe compatibility path is
defined.
## Reproduction
1. Create a Lance dataset with one vector column.
2. Create two named logical indexes on that column, one using L2 and one
using cosine, ensuring the L2 index is returned first by `describeIndices()`.
3. Run Doris `vector_search()` with `metric=cosine` and `use_index=true`.
4. Inspect `EXPLAIN`.
Current behavior:
```text
lanceSearchIndexSegments=0
```
and the query falls back to fragment search, even though the cosine index
exists.
Expected behavior:
```text
lanceSearchIndexSegments>0
```
with only the `vec_cosine` physical segments assigned to indexed splits.
## Acceptance criteria
- [ ] FE unit test: L2 index appears first, cosine index second, and a
cosine query selects the cosine segments.
- [ ] FE unit test: reversing metadata order does not change the selected
metric-compatible logical index.
- [ ] FE unit test: segments from different logical index names are never
mixed in one index plan.
- [ ] FE unit test: no compatible metric still produces the existing Flat
Search fallback.
- [ ] FE unit test: omitted/`DEFAULT` metric follows the documented Doris L2
default.
- [ ] Regression test proves physical indexed execution, using both
`EXPLAIN` segment planning and an `nprobes`/`ef` discriminator rather than only
comparing indexed and flat results.
- [ ] Documentation no longer recommends one index per vector column solely
because Doris cannot find a later metric-compatible index.
## Related
- #66340
- apache/doris#67039 currently uses one vector column per matrix cell to
avoid this selection limitation; it expands coverage but does not change the
production selection logic.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]