Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog/130564.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 130564
summary: Enable early termination for HNSW by default
area: Vector Search
type: enhancement
issues: []
4 changes: 2 additions & 2 deletions docs/reference/elasticsearch/index-settings/index-modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ $$$index-refresh-interval-setting$$$
: How often to perform a refresh operation, which makes recent changes to the index visible to search. If this setting is not explicitly set, shards that haven’t seen search traffic for at least `index.search.idle.after` seconds will not receive background refreshes until they receive a search request. Searches that hit an idle shard where a refresh is pending will trigger a refresh as part of the search operation for that shard only. This behavior aims to automatically optimize bulk indexing in the default case when no searches are performed. To opt out of this behavior, set an explicit value for the refresh interval, even if it matches the default value.

The value defaults to `1s` in {{stack}} and `5s` in {{serverless-short}}. In {{serverless-short}}, `5s` is also the minimum value that can be set.

In both cases, the setting can be set to `-1` to disable refresh.

$$$index-max-result-window$$$
Expand Down Expand Up @@ -270,4 +270,4 @@ $$$index-esql-stored-fields-sequential-proportion$$$
: Tuning parameter for deciding when {{esql}} will load [stored fields](/reference/elasticsearch/rest-apis/retrieve-selected-fields.md#stored-fields) using a strategy tuned for loading dense sequence of documents. Allows values between 0.0 and 1.0 and defaults to 0.2. Indices with documents smaller than 10kb may see speed improvements loading `text` fields by setting this lower.

$$$index-dense-vector-hnsw-early-termination$$$ `index.dense_vector.hnsw_early_termination` {applies_to}`stack: ga 9.2` {applies_to}`serverless: all`
: Whether to apply _patience_ based early termination strategy to knn queries over HNSW graphs (see [paper](https://cs.uwaterloo.ca/~jimmylin/publications/Teofili_Lin_ECIR2025.pdf)). This is only applicable to `dense_vector` fields with `hnsw`, `int8_hnsw`, `int4_hnsw` and `bbq_hnsw` index types. Defaults to `false`.
: Whether to apply _patience_ based early termination strategy to knn queries over HNSW graphs (see [paper](https://cs.uwaterloo.ca/~jimmylin/publications/Teofili_Lin_ECIR2025.pdf)). This is only applicable to `dense_vector` fields with `hnsw`, `int8_hnsw`, `int4_hnsw` and `bbq_hnsw` index types. Defaults to `true`.
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ public void testFilteredQueryStrategy() {
}

public void testHnswEarlyTerminationQuery() {
client().admin()
.indices()
.prepareUpdateSettings(INDEX_NAME)
.setSettings(Settings.builder().put(DenseVectorFieldMapper.HNSW_EARLY_TERMINATION.getKey(), false))
.get();
float[] vector = new float[16];
randomVector(vector, 25);
int upperLimit = 35;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public class DenseVectorFieldMapper extends FieldMapper {
private static final float EPS = 1e-3f;
public static final int BBQ_MIN_DIMS = 64;

private static final boolean DEFAULT_HNSW_EARLY_TERMINATION = false;
private static final boolean DEFAULT_HNSW_EARLY_TERMINATION = true;

public static boolean isNotUnitVector(float magnitude) {
return Math.abs(magnitude - 1.0f) > EPS;
Expand Down
Loading