This is an automated email from the ASF dual-hosted git repository. dsmiley pushed a commit to branch branch_9x in repository https://gitbox.apache.org/repos/asf/solr.git
commit 66e43fdfe0de0fc563c41101735e67d28442ca3e Author: Adam Quigley <[email protected]> AuthorDate: Wed Jul 1 04:34:54 2026 -0400 SOLR-18267: Add flat vector index with no HNSW (#4492) Adapted for branch_9x: BinaryQuantizedDenseVectorField (not on 9.x) and the cagra_hnsw algorithm references were dropped; tests and docs adjusted to 9.x. (cherry picked from commit 07036ab1c700a1ead8282482d495b17b17bf0387) (cherry picked from commit bec1acb9af50f5969f570349d3f535359001ab18) --- .../SOLR-18267-add-flat-vector-index.yml | 7 + .../org/apache/solr/core/SchemaCodecFactory.java | 3 +- .../apache/solr/core/Solr101FlatVectorFormat.java | 66 +++++++++ .../org/apache/solr/schema/DenseVectorField.java | 15 +- .../schema/ScalarQuantizedDenseVectorField.java | 6 + .../org/apache/solr/search/neural/KnnQParser.java | 8 + .../search/neural/VectorSimilarityQParser.java | 8 + .../org.apache.lucene.codecs.KnnVectorsFormat | 16 ++ ...bad-schema-densevector-flat-scalarQuantized.xml | 29 ++++ .../collection1/conf/schema-densevector-flat.xml | 31 ++++ .../apache/solr/schema/DenseVectorFieldTest.java | 164 +++++++++++++++++++++ .../ScalarQuantizedDenseVectorFieldTest.java | 12 +- .../query-guide/pages/dense-vector-search.adoc | 17 ++- 13 files changed, 374 insertions(+), 8 deletions(-) diff --git a/changelog/unreleased/SOLR-18267-add-flat-vector-index.yml b/changelog/unreleased/SOLR-18267-add-flat-vector-index.yml new file mode 100644 index 00000000000..94bb9c5b7f2 --- /dev/null +++ b/changelog/unreleased/SOLR-18267-add-flat-vector-index.yml @@ -0,0 +1,7 @@ +title: Add knnAlgorithm="flat" option to DenseVectorField to skip HNSW graph construction for exact vector search +type: added +authors: +- name: Adam Quigley +links: +- name: SOLR-18267 + url: https://issues.apache.org/jira/browse/SOLR-18267 \ No newline at end of file diff --git a/solr/core/src/java/org/apache/solr/core/SchemaCodecFactory.java b/solr/core/src/java/org/apache/solr/core/SchemaCodecFactory.java index 60c306ee8ef..bce61a6d41f 100644 --- a/solr/core/src/java/org/apache/solr/core/SchemaCodecFactory.java +++ b/solr/core/src/java/org/apache/solr/core/SchemaCodecFactory.java @@ -129,7 +129,8 @@ public class SchemaCodecFactory extends CodecFactory implements SolrCoreAware { if (fieldType instanceof DenseVectorField) { DenseVectorField vectorField = (DenseVectorField) fieldType; final String knnAlgorithm = vectorField.getKnnAlgorithm(); - if (!DenseVectorField.HNSW_ALGORITHM.equals(knnAlgorithm)) { + if (!DenseVectorField.HNSW_ALGORITHM.equals(knnAlgorithm) + && !DenseVectorField.FLAT_ALGORITHM.equals(knnAlgorithm)) { throw new SolrException( ErrorCode.SERVER_ERROR, knnAlgorithm + " KNN algorithm is not supported"); } diff --git a/solr/core/src/java/org/apache/solr/core/Solr101FlatVectorFormat.java b/solr/core/src/java/org/apache/solr/core/Solr101FlatVectorFormat.java new file mode 100644 index 00000000000..d81119f0156 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/core/Solr101FlatVectorFormat.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.core; + +import java.io.IOException; +import org.apache.lucene.codecs.KnnVectorsFormat; +import org.apache.lucene.codecs.KnnVectorsReader; +import org.apache.lucene.codecs.KnnVectorsWriter; +import org.apache.lucene.codecs.hnsw.FlatVectorScorerUtil; +import org.apache.lucene.codecs.lucene99.Lucene99FlatVectorsFormat; +import org.apache.lucene.index.SegmentReadState; +import org.apache.lucene.index.SegmentWriteState; + +/** + * SPI-registered wrapper for {@link Lucene99FlatVectorsFormat}, which Lucene does not register as a + * {@link KnnVectorsFormat} in SPI. + * + * @lucene.spi {@value #NAME} + * @since 10.1 + */ +public final class Solr101FlatVectorFormat extends KnnVectorsFormat { + + static final String NAME = "Solr101FlatVectorFormat"; + + private final Lucene99FlatVectorsFormat delegate; + + public Solr101FlatVectorFormat() { + super(NAME); + this.delegate = + new Lucene99FlatVectorsFormat(FlatVectorScorerUtil.getLucene99FlatVectorsScorer()); + } + + @Override + public KnnVectorsWriter fieldsWriter(SegmentWriteState state) throws IOException { + return delegate.fieldsWriter(state); + } + + @Override + public KnnVectorsReader fieldsReader(SegmentReadState state) throws IOException { + return delegate.fieldsReader(state); + } + + @Override + public int getMaxDimensions(String fieldName) { + return delegate.getMaxDimensions(fieldName); + } + + @Override + public String toString() { + return NAME; + } +} diff --git a/solr/core/src/java/org/apache/solr/schema/DenseVectorField.java b/solr/core/src/java/org/apache/solr/schema/DenseVectorField.java index 5e29d69b6a6..acefae003f7 100644 --- a/solr/core/src/java/org/apache/solr/schema/DenseVectorField.java +++ b/solr/core/src/java/org/apache/solr/schema/DenseVectorField.java @@ -45,6 +45,7 @@ import org.apache.lucene.search.SortField; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.hnsw.HnswGraph; import org.apache.solr.common.SolrException; +import org.apache.solr.core.Solr101FlatVectorFormat; import org.apache.solr.search.QParser; import org.apache.solr.uninverting.UninvertingReader; import org.apache.solr.util.vector.ByteDenseVectorParser; @@ -66,6 +67,7 @@ import org.slf4j.LoggerFactory; public class DenseVectorField extends FloatPointField { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); public static final String HNSW_ALGORITHM = "hnsw"; + public static final String FLAT_ALGORITHM = "flat"; public static final String DEFAULT_KNN_ALGORITHM = HNSW_ALGORITHM; static final String KNN_VECTOR_DIMENSION = "vectorDimension"; static final String KNN_ALGORITHM = "knnAlgorithm"; @@ -344,7 +346,11 @@ public class DenseVectorField extends FloatPointField { } public KnnVectorsFormat buildKnnVectorsFormat() { - return new Lucene99HnswVectorsFormat(hnswMaxConn, hnswBeamWidth); + if (FLAT_ALGORITHM.equals(knnAlgorithm)) { + return new Solr101FlatVectorFormat(); + } else { + return new Lucene99HnswVectorsFormat(hnswMaxConn, hnswBeamWidth); + } } @Override @@ -369,6 +375,13 @@ public class DenseVectorField extends FloatPointField { public Query getKnnVectorQuery( String fieldName, String vectorToSearch, int topK, Query filterQuery) { + if (FLAT_ALGORITHM.equals(knnAlgorithm)) { + throw new SolrException( + SolrException.ErrorCode.BAD_REQUEST, + "KNN vector queries are not supported for fields using knnAlgorithm=\"flat\". " + + "Use vectorSimilarity() function queries instead."); + } + DenseVectorParser vectorBuilder = getVectorBuilder(vectorToSearch, DenseVectorParser.BuilderPhase.QUERY); diff --git a/solr/core/src/java/org/apache/solr/schema/ScalarQuantizedDenseVectorField.java b/solr/core/src/java/org/apache/solr/schema/ScalarQuantizedDenseVectorField.java index 885d09cea17..dfee66ee074 100644 --- a/solr/core/src/java/org/apache/solr/schema/ScalarQuantizedDenseVectorField.java +++ b/solr/core/src/java/org/apache/solr/schema/ScalarQuantizedDenseVectorField.java @@ -91,6 +91,12 @@ public class ScalarQuantizedDenseVectorField extends DenseVectorField { } super.init(schema, args); + + if (FLAT_ALGORITHM.equals(getKnnAlgorithm())) { + throw new SolrException( + SolrException.ErrorCode.BAD_REQUEST, + "knnAlgorithm 'flat' is not supported for ScalarQuantizedDenseVectorField"); + } } @Override diff --git a/solr/core/src/java/org/apache/solr/search/neural/KnnQParser.java b/solr/core/src/java/org/apache/solr/search/neural/KnnQParser.java index e0b74105e39..2410e5ab69d 100644 --- a/solr/core/src/java/org/apache/solr/search/neural/KnnQParser.java +++ b/solr/core/src/java/org/apache/solr/search/neural/KnnQParser.java @@ -52,6 +52,14 @@ public class KnnQParser extends AbstractVectorQParserBase { final String vectorField = getFieldName(); final SchemaField schemaField = req.getSchema().getField(vectorField); final DenseVectorField denseVectorType = getCheckedFieldType(schemaField); + + if (DenseVectorField.FLAT_ALGORITHM.equals(denseVectorType.getKnnAlgorithm())) { + throw new SolrException( + SolrException.ErrorCode.BAD_REQUEST, + "The {!knn} query parser is not supported for fields using knnAlgorithm=\"flat\". " + + "Use vectorSimilarity() function queries instead."); + } + final String vectorToSearch = getVectorToSearch(); final int topK = localParams.getInt(TOP_K, DEFAULT_TOP_K); diff --git a/solr/core/src/java/org/apache/solr/search/neural/VectorSimilarityQParser.java b/solr/core/src/java/org/apache/solr/search/neural/VectorSimilarityQParser.java index 112df600fd5..2b014c6abd8 100644 --- a/solr/core/src/java/org/apache/solr/search/neural/VectorSimilarityQParser.java +++ b/solr/core/src/java/org/apache/solr/search/neural/VectorSimilarityQParser.java @@ -46,6 +46,14 @@ public class VectorSimilarityQParser extends AbstractVectorQParserBase { final String fieldName = getFieldName(); final SchemaField schemaField = req.getSchema().getField(fieldName); final DenseVectorField denseVectorType = getCheckedFieldType(schemaField); + + if (DenseVectorField.FLAT_ALGORITHM.equals(denseVectorType.getKnnAlgorithm())) { + throw new SolrException( + SolrException.ErrorCode.BAD_REQUEST, + "The {!vectorSimilarity} query parser is not supported for fields using knnAlgorithm=\"flat\". " + + "Use vectorSimilarity() function queries instead."); + } + final String vectorToSearch = getVectorToSearch(); final float minTraverse = localParams.getFloat(MIN_TRAVERSE, DEFAULT_MIN_TRAVERSE); final Float minReturn = localParams.getFloat(MIN_RETURN); diff --git a/solr/core/src/resources/META-INF/services/org.apache.lucene.codecs.KnnVectorsFormat b/solr/core/src/resources/META-INF/services/org.apache.lucene.codecs.KnnVectorsFormat new file mode 100644 index 00000000000..2e6fda571db --- /dev/null +++ b/solr/core/src/resources/META-INF/services/org.apache.lucene.codecs.KnnVectorsFormat @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +org.apache.solr.core.Solr101FlatVectorFormat diff --git a/solr/core/src/test-files/solr/collection1/conf/bad-schema-densevector-flat-scalarQuantized.xml b/solr/core/src/test-files/solr/collection1/conf/bad-schema-densevector-flat-scalarQuantized.xml new file mode 100644 index 00000000000..365bddd03e7 --- /dev/null +++ b/solr/core/src/test-files/solr/collection1/conf/bad-schema-densevector-flat-scalarQuantized.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" ?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- Test schema file for DenseVectorField --> + +<schema name="bad-schema-densevector-flat-quantized" version="1.7"> + <fieldType name="string" class="solr.StrField" multiValued="true"/> + <fieldType name="knn_vector_flat_sq" class="solr.ScalarQuantizedDenseVectorField" vectorDimension="4" similarityFunction="cosine" knnAlgorithm="flat"/> + + <field name="id" type="string" indexed="true" stored="true" multiValued="false" required="false"/> + <field name="vector" type="knn_vector_flat_sq" indexed="true" stored="true"/> + + <uniqueKey>id</uniqueKey> +</schema> diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-densevector-flat.xml b/solr/core/src/test-files/solr/collection1/conf/schema-densevector-flat.xml new file mode 100644 index 00000000000..a1e66ee3aa2 --- /dev/null +++ b/solr/core/src/test-files/solr/collection1/conf/schema-densevector-flat.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" ?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- Test schema file for DenseVectorField with flat (non-HNSW) algorithm --> + +<schema name="schema-densevector-flat" version="1.7"> + <fieldType name="string" class="solr.StrField" multiValued="true"/> + <fieldType name="knn_vector_flat" class="solr.DenseVectorField" vectorDimension="4" similarityFunction="cosine" knnAlgorithm="flat"/> + <fieldType name="knn_vector_flat_byte" class="solr.DenseVectorField" vectorDimension="4" similarityFunction="cosine" knnAlgorithm="flat" vectorEncoding="BYTE"/> + + <field name="id" type="string" indexed="true" stored="true" multiValued="false" required="false"/> + <field name="vector_flat" type="knn_vector_flat" indexed="true" stored="true"/> + <field name="vector_flat_byte" type="knn_vector_flat_byte" indexed="true" stored="true"/> + + <uniqueKey>id</uniqueKey> +</schema> diff --git a/solr/core/src/test/org/apache/solr/schema/DenseVectorFieldTest.java b/solr/core/src/test/org/apache/solr/schema/DenseVectorFieldTest.java index 3ee93ae369e..542c1e2d66d 100644 --- a/solr/core/src/test/org/apache/solr/schema/DenseVectorFieldTest.java +++ b/solr/core/src/test/org/apache/solr/schema/DenseVectorFieldTest.java @@ -770,4 +770,168 @@ public class DenseVectorFieldTest extends AbstractBadConfigTestBase { deleteCore(); } } + + @Test + public void fieldDefinition_flatAlgorithm_shouldLoadSchemaField() throws Exception { + try { + initCore("solrconfig_codec.xml", "schema-densevector-flat.xml"); + IndexSchema schema = h.getCore().getLatestSchema(); + + SchemaField vector = schema.getField("vector_flat"); + assertNotNull(vector); + + DenseVectorField type = (DenseVectorField) vector.getType(); + assertThat(type.getKnnAlgorithm(), is("flat")); + assertThat(type.getDimension(), is(4)); + assertThat(type.getSimilarityFunction(), is(VectorSimilarityFunction.COSINE)); + + assertTrue(vector.indexed()); + assertTrue(vector.stored()); + } finally { + deleteCore(); + } + } + + @Test + public void flatAlgorithm_knnQuery_shouldThrowException() throws Exception { + try { + initCore("solrconfig_codec.xml", "schema-densevector-flat.xml"); + + assertQEx( + "Running {!knn} on a flat vector field should raise an Exception", + "knnAlgorithm=\"flat\"", + req("q", "{!knn f=vector_flat topK=2}[1, 2, 3, 4]", "fl", "id"), + SolrException.ErrorCode.BAD_REQUEST); + } finally { + deleteCore(); + } + } + + @Test + public void flatAlgorithm_vectorSimilarityFunction_shouldReturnResults() throws Exception { + try { + initCore("solrconfig_codec.xml", "schema-densevector-flat.xml"); + + SolrInputDocument doc1 = new SolrInputDocument(); + doc1.addField("id", "0"); + doc1.addField("vector_flat", Arrays.asList(1, 2, 3, 4)); + assertU(adoc(doc1)); + + SolrInputDocument doc2 = new SolrInputDocument(); + doc2.addField("id", "1"); + doc2.addField("vector_flat", Arrays.asList(2, 3, 4, 5)); + assertU(adoc(doc2)); + + SolrInputDocument doc3 = new SolrInputDocument(); + doc3.addField("id", "2"); + doc3.addField("vector_flat", Arrays.asList(100, 200, 50, 25)); + assertU(adoc(doc3)); + + assertU(commit()); + + assertJQ( + req( + "q", "{!func}vectorSimilarity(vector_flat,[1, 2, 3, 4])", + "fl", "id,score"), + "/response/numFound==3", + "/response/docs/[0]/id=='0'", + "/response/docs/[0]/score==1.0"); + + // Filtered test + assertJQ( + req( + "q", "{!func}vectorSimilarity(vector_flat,[1, 2, 3, 4])", + "fq", "id:(0 2)", + "fl", "id,score"), + "/response/numFound==2", + "/response/docs/[0]/id=='0'", + "/response/docs/[0]/score==1.0"); + } finally { + deleteCore(); + } + } + + @Test + public void flatAlgorithm_storedField_shouldBeReturnedInResults() throws Exception { + try { + initCore("solrconfig_codec.xml", "schema-densevector-flat.xml"); + + SolrInputDocument doc1 = new SolrInputDocument(); + doc1.addField("id", "0"); + doc1.addField("vector_flat", Arrays.asList(1.1f, 2.2f, 3.3f, 4.4f)); + assertU(adoc(doc1)); + assertU(commit()); + + assertJQ( + req("q", "id:0", "fl", "vector_flat"), + "/response/docs/[0]=={'vector_flat':[1.1,2.2,3.3,4.4]}"); + } finally { + deleteCore(); + } + } + + @Test + public void flatAlgorithm_byteEncoding_shouldWork() throws Exception { + try { + initCore("solrconfig_codec.xml", "schema-densevector-flat.xml"); + + SolrInputDocument doc1 = new SolrInputDocument(); + doc1.addField("id", "0"); + doc1.addField("vector_flat_byte", Arrays.asList(1, 2, 3, 4)); + assertU(adoc(doc1)); + + SolrInputDocument doc2 = new SolrInputDocument(); + doc2.addField("id", "1"); + doc2.addField("vector_flat_byte", Arrays.asList(5, 6, 7, 8)); + assertU(adoc(doc2)); + + assertU(commit()); + + assertJQ( + req( + "q", "{!func}vectorSimilarity(vector_flat_byte,[1, 2, 3, 4])", + "fl", "id,score"), + "/response/numFound==2", + "/response/docs/[0]/id=='0'", + "/response/docs/[0]/score==1.0"); + } finally { + deleteCore(); + } + } + + @Test + public void flatAlgorithm_vectorSimilarityQParser_shouldThrowException() throws Exception { + try { + initCore("solrconfig_codec.xml", "schema-densevector-flat.xml"); + + assertQEx( + "Running {!vectorSimilarity} on a flat vector field should raise an Exception", + "knnAlgorithm=\"flat\"", + req( + "q", "{!vectorSimilarity f=vector_flat minReturn=0.99}[1, 2, 3, 4]", + "fl", "id"), + SolrException.ErrorCode.BAD_REQUEST); + } finally { + deleteCore(); + } + } + + @Test + public void flatAlgorithm_getKnnVectorQuery_shouldThrowException() throws Exception { + try { + initCore("solrconfig_codec.xml", "schema-densevector-flat.xml"); + IndexSchema schema = h.getCore().getLatestSchema(); + SchemaField vectorField = schema.getField("vector_flat"); + assertNotNull(vectorField); + DenseVectorField type = (DenseVectorField) vectorField.getType(); + + SolrException ex = + expectThrows( + SolrException.class, + () -> type.getKnnVectorQuery("vector_flat", "[1, 2, 3, 4]", 3, null)); + assertTrue(ex.getMessage().contains("knnAlgorithm=\"flat\"")); + } finally { + deleteCore(); + } + } } diff --git a/solr/core/src/test/org/apache/solr/schema/ScalarQuantizedDenseVectorFieldTest.java b/solr/core/src/test/org/apache/solr/schema/ScalarQuantizedDenseVectorFieldTest.java index 70a239600f6..ccfef3d0586 100644 --- a/solr/core/src/test/org/apache/solr/schema/ScalarQuantizedDenseVectorFieldTest.java +++ b/solr/core/src/test/org/apache/solr/schema/ScalarQuantizedDenseVectorFieldTest.java @@ -21,13 +21,9 @@ import static org.hamcrest.core.Is.is; import org.apache.lucene.codecs.lucene99.Lucene99ScalarQuantizedVectorsFormat; import org.apache.lucene.index.VectorSimilarityFunction; import org.apache.solr.core.AbstractBadConfigTestBase; -import org.junit.Before; import org.junit.Test; public class ScalarQuantizedDenseVectorFieldTest extends AbstractBadConfigTestBase { - @Before - public void init() {} - @Test public void fieldTypeDefinition_invalidBitSize_shouldThrowException() throws Exception { assertConfigs( @@ -160,4 +156,12 @@ public class ScalarQuantizedDenseVectorFieldTest extends AbstractBadConfigTestBa deleteCore(); } } + + @Test + public void fieldDefinition_flatAlgorithm_shouldThrowException() throws Exception { + assertConfigs( + "solrconfig-basic.xml", + "bad-schema-densevector-flat-scalarQuantized.xml", + "knnAlgorithm 'flat' is not supported for ScalarQuantizedDenseVectorField"); + } } diff --git a/solr/solr-ref-guide/modules/query-guide/pages/dense-vector-search.adoc b/solr/solr-ref-guide/modules/query-guide/pages/dense-vector-search.adoc index edc25b39ab9..18e97193ca1 100644 --- a/solr/solr-ref-guide/modules/query-guide/pages/dense-vector-search.adoc +++ b/solr/solr-ref-guide/modules/query-guide/pages/dense-vector-search.adoc @@ -122,8 +122,10 @@ Here's how `DenseVectorField` can be configured with the advanced hyperparameter (advanced) Specifies the underlying knn algorithm to use + -Accepted values: `hnsw`. - +Accepted values: `hnsw`, `flat`. ++ +The `flat` algorithm stores vectors without building an HNSW graph. This avoids the indexing overhead of graph construction, but does not support the `{!knn}` query parser. Use `vectorSimilarity()` function queries to score and rank documents by vector similarity. See <<Flat Vector Index>> for details. ++ Please note that the `knnAlgorithm` accepted values may change in future releases. `vectorEncoding`:: @@ -704,6 +706,17 @@ The final ranked list of results will have the first pass score(main query `q`) Details about using the ReRank Query Parser can be found in the xref:query-guide:query-re-ranking.adoc[Query Re-Ranking] section. ==== +== Flat Vector Index + +Setting `knnAlgorithm="flat"` stores vectors without building an HNSW graph, avoiding the indexing cost of graph construction. + +Flat fields do not support the `{!knn}`, `{!knn_text_to_vector}`, or `{!vectorSimilarity}` query parsers. +Use `vectorSimilarity()` function queries to score and rank by similarity: + +[source] +q={!func}vectorSimilarity(vector,[1.0, 2.0, 3.0, 4.0])&fl=id,score + + == Additional Resources * Blog: https://sease.io/2022/01/apache-solr-neural-search.html
