Skip to content

Commit d9243c8

Browse files
authored
Merge branch 'main' into fix-failure-store-removing-allocator-settings
2 parents 49b465d + d6c20bd commit d9243c8

File tree

101 files changed

+686
-321
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+686
-321
lines changed

docs/changelog/131081.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 131081
2+
summary: Fix knn search error when dimensions are not set
3+
area: Vector Search
4+
type: bug
5+
issues:
6+
- 129550

docs/reference/query-languages/query-dsl/query-dsl-bool-query.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ A query that matches documents matching boolean combinations of other queries. T
1313
| --- | --- |
1414
| `must` | The clause (query) must appear in matching documents and will contribute to the score. Each query defined under a `must` acts as a logical "AND", returning only documents that match *all* the specified queries. |
1515
| `should` | The clause (query) should appear in the matching document. Each query defined under a `should` acts as a logical "OR", returning documents that match *any* of the specified queries. |
16-
| `filter` | The clause (query) must appear in matching documents. However unlike`must` the score of the query will be ignored. Filter clauses are executedin [filter context](/reference/query-languages/query-dsl/query-filter-context.md), meaning that scoring is ignoredand clauses are considered for caching. Each query defined under a `filter` acts as a logical "AND", returning only documents that match *all* the specified queries. |
17-
| `must_not` | The clause (query) must not appear in the matchingdocuments. Clauses are executed in [filter context](/reference/query-languages/query-dsl/query-filter-context.md) meaningthat scoring is ignored and clauses are considered for caching. Because scoring isignored, a score of `0` for all documents is returned. Each query defined under a `must_not` acts as a logical "NOT", returning only documents that do not match any of the specified queries. |
16+
| `filter` | The clause (query) must appear in matching documents. However unlike `must` the score of the query will be ignored. Filter clauses are executed in [filter context](/reference/query-languages/query-dsl/query-filter-context.md), meaning that scoring is ignored and clauses are considered for caching. Each query defined under a `filter` acts as a logical "AND", returning only documents that match *all* the specified queries. |
17+
| `must_not` | The clause (query) must not appear in the matching documents. Clauses are executed in [filter context](/reference/query-languages/query-dsl/query-filter-context.md) meaning that scoring is ignored and clauses are considered for caching. Because scoring is ignored, a score of `0` for all documents is returned. Each query defined under a `must_not` acts as a logical "NOT", returning only documents that do not match any of the specified queries. |
1818

1919
The `must` and `should` clauses function as logical AND, OR operators, contributing to the scoring of results. However, these results are not cached, which means repeated queries won't benefit from faster retrieval. In contrast, the `filter` and `must_not` clauses are used to include or exclude results without impacting the score, unless used within a `constant_score` query.
2020

docs/reference/query-languages/query-dsl/query-dsl-knn-query.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ POST my-image-index/_search
165165

166166
Knn query can be used as a part of hybrid search, where knn query is combined with other lexical queries. For example, the query below finds documents with `title` matching `mountain lake`, and combines them with the top 10 documents that have the closest image vectors to the `query_vector`. The combined documents are then scored and the top 3 top scored documents are returned.
167167

168-
+
169168

170169
```console
171170
POST my-image-index/_search

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.vectors/40_knn_search.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,3 +670,36 @@ setup:
670670
properties:
671671
embedding:
672672
type: dense_vector
673+
674+
675+
---
676+
"Searching with no data dimensions specified":
677+
- requires:
678+
cluster_features: "search.vectors.no_dimensions_bugfix"
679+
reason: "Search with no dimensions bugfix"
680+
681+
- do:
682+
indices.create:
683+
index: empty-test
684+
body:
685+
mappings:
686+
properties:
687+
vector:
688+
type: dense_vector
689+
index: true
690+
691+
- do:
692+
search:
693+
index: empty-test
694+
body:
695+
fields: [ "name" ]
696+
knn:
697+
field: vector
698+
query_vector: [ -0.5, 90.0, -10, 14.8, -156.0 ]
699+
k: 3
700+
num_candidates: 3
701+
rescore_vector:
702+
oversample: 1.5
703+
similarity: 0.1
704+
705+
- match: { hits.total.value: 0 }

server/src/main/java/org/elasticsearch/common/util/concurrent/EsExecutors.java

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ public void rejectedExecution(Runnable task, ThreadPoolExecutor executor) {
577577
}
578578

579579
public static class TaskTrackingConfig {
580+
// This is a random starting point alpha.
580581
public static final double DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST = 0.3;
581582

582583
private final boolean trackExecutionTime;
@@ -597,17 +598,6 @@ public static class TaskTrackingConfig {
597598
DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST
598599
);
599600

600-
public TaskTrackingConfig(boolean trackOngoingTasks, double executionTimeEWMAAlpha) {
601-
this(true, trackOngoingTasks, false, executionTimeEWMAAlpha);
602-
}
603-
604-
/**
605-
* Execution tracking enabled constructor, with extra options to enable further specialized tracking.
606-
*/
607-
public TaskTrackingConfig(boolean trackOngoingTasks, boolean trackMaxQueueLatency, double executionTimeEwmaAlpha) {
608-
this(true, trackOngoingTasks, trackMaxQueueLatency, executionTimeEwmaAlpha);
609-
}
610-
611601
/**
612602
* @param trackExecutionTime Whether to track execution stats
613603
* @param trackOngoingTasks Whether to track ongoing task execution time, not just finished tasks
@@ -641,6 +631,39 @@ public boolean trackMaxQueueLatency() {
641631
public double getExecutionTimeEwmaAlpha() {
642632
return executionTimeEwmaAlpha;
643633
}
634+
635+
public static Builder builder() {
636+
return new Builder();
637+
}
638+
639+
public static class Builder {
640+
private boolean trackExecutionTime = false;
641+
private boolean trackOngoingTasks = false;
642+
private boolean trackMaxQueueLatency = false;
643+
private double ewmaAlpha = DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST;
644+
645+
public Builder() {}
646+
647+
public Builder trackExecutionTime(double alpha) {
648+
trackExecutionTime = true;
649+
ewmaAlpha = alpha;
650+
return this;
651+
}
652+
653+
public Builder trackOngoingTasks() {
654+
trackOngoingTasks = true;
655+
return this;
656+
}
657+
658+
public Builder trackMaxQueueLatency() {
659+
trackMaxQueueLatency = true;
660+
return this;
661+
}
662+
663+
public TaskTrackingConfig build() {
664+
return new TaskTrackingConfig(trackExecutionTime, trackOngoingTasks, trackMaxQueueLatency, ewmaAlpha);
665+
}
666+
}
644667
}
645668

646669
}

server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.apache.lucene.search.FieldExistsQuery;
3636
import org.apache.lucene.search.KnnByteVectorQuery;
3737
import org.apache.lucene.search.KnnFloatVectorQuery;
38+
import org.apache.lucene.search.MatchNoDocsQuery;
3839
import org.apache.lucene.search.PatienceKnnVectorQuery;
3940
import org.apache.lucene.search.Query;
4041
import org.apache.lucene.search.join.BitSetProducer;
@@ -2530,6 +2531,9 @@ public Query createKnnQuery(
25302531
"to perform knn search on field [" + name() + "], its mapping must have [index] set to [true]"
25312532
);
25322533
}
2534+
if (dims == null) {
2535+
return new MatchNoDocsQuery("No data has been indexed for field [" + name() + "]");
2536+
}
25332537
KnnSearchStrategy knnSearchStrategy = heuristic.getKnnSearchStrategy();
25342538
return switch (getElementType()) {
25352539
case BYTE -> createKnnByteQuery(

server/src/main/java/org/elasticsearch/search/SearchFeatures.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public Set<NodeFeature> getFeatures() {
3232
public static final NodeFeature INT_SORT_FOR_INT_SHORT_BYTE_FIELDS = new NodeFeature("search.sort.int_sort_for_int_short_byte_fields");
3333
static final NodeFeature MULTI_MATCH_CHECKS_POSITIONS = new NodeFeature("search.multi.match.checks.positions");
3434
public static final NodeFeature BBQ_HNSW_DEFAULT_INDEXING = new NodeFeature("search.vectors.mappers.default_bbq_hnsw");
35+
public static final NodeFeature SEARCH_WITH_NO_DIMENSIONS_BUGFIX = new NodeFeature("search.vectors.no_dimensions_bugfix");
3536

3637
@Override
3738
public Set<NodeFeature> getTestFeatures() {
@@ -41,7 +42,8 @@ public Set<NodeFeature> getTestFeatures() {
4142
RESCORER_MISSING_FIELD_BAD_REQUEST,
4243
INT_SORT_FOR_INT_SHORT_BYTE_FIELDS,
4344
MULTI_MATCH_CHECKS_POSITIONS,
44-
BBQ_HNSW_DEFAULT_INDEXING
45+
BBQ_HNSW_DEFAULT_INDEXING,
46+
SEARCH_WITH_NO_DIMENSIONS_BUGFIX
4547
);
4648
}
4749
}

server/src/main/java/org/elasticsearch/threadpool/DefaultBuiltInExecutorBuilders.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ public Map<String, ExecutorBuilder> getBuilders(Settings settings, int allocated
5656
allocatedProcessors,
5757
// 10,000 for all nodes with 8 cores or fewer. Scale up once we have more than 8 cores.
5858
Math.max(allocatedProcessors * 750, 10000),
59-
new EsExecutors.TaskTrackingConfig(true, true, indexAutoscalingEWMA)
59+
EsExecutors.TaskTrackingConfig.builder()
60+
.trackOngoingTasks()
61+
.trackMaxQueueLatency()
62+
.trackExecutionTime(indexAutoscalingEWMA)
63+
.build()
6064
)
6165
);
6266
int searchOrGetThreadPoolSize = ThreadPool.searchOrGetThreadPoolSize(allocatedProcessors);
@@ -81,7 +85,7 @@ public Map<String, ExecutorBuilder> getBuilders(Settings settings, int allocated
8185
ThreadPool.Names.SEARCH,
8286
searchOrGetThreadPoolSize,
8387
searchOrGetThreadPoolSize * 1000,
84-
new EsExecutors.TaskTrackingConfig(true, searchAutoscalingEWMA)
88+
EsExecutors.TaskTrackingConfig.builder().trackOngoingTasks().trackExecutionTime(searchAutoscalingEWMA).build()
8589
)
8690
);
8791
result.put(
@@ -91,7 +95,7 @@ public Map<String, ExecutorBuilder> getBuilders(Settings settings, int allocated
9195
ThreadPool.Names.SEARCH_COORDINATION,
9296
halfProc,
9397
1000,
94-
new EsExecutors.TaskTrackingConfig(true, searchAutoscalingEWMA)
98+
EsExecutors.TaskTrackingConfig.builder().trackOngoingTasks().trackExecutionTime(searchAutoscalingEWMA).build()
9599
)
96100
);
97101
result.put(
@@ -195,7 +199,7 @@ public Map<String, ExecutorBuilder> getBuilders(Settings settings, int allocated
195199
ThreadPool.Names.SYSTEM_WRITE,
196200
halfProcMaxAt5,
197201
1000,
198-
new EsExecutors.TaskTrackingConfig(true, indexAutoscalingEWMA),
202+
EsExecutors.TaskTrackingConfig.builder().trackOngoingTasks().trackExecutionTime(indexAutoscalingEWMA).build(),
199203
true
200204
)
201205
);
@@ -228,7 +232,7 @@ public Map<String, ExecutorBuilder> getBuilders(Settings settings, int allocated
228232
ThreadPool.Names.SYSTEM_CRITICAL_WRITE,
229233
halfProcMaxAt5,
230234
1500,
231-
new EsExecutors.TaskTrackingConfig(true, indexAutoscalingEWMA),
235+
EsExecutors.TaskTrackingConfig.builder().trackOngoingTasks().trackExecutionTime(indexAutoscalingEWMA).build(),
232236
true
233237
)
234238
);

server/src/test/java/org/elasticsearch/common/util/concurrent/EsExecutorsTests.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,7 @@ public void testScalingWithTaskTimeTracking() {
675675
final int max = between(min + 1, 6);
676676

677677
{
678+
var executionTimeEwma = randomDoubleBetween(0.01, 0.1, true);
678679
ThreadPoolExecutor pool = EsExecutors.newScaling(
679680
getClass().getName() + "/" + getTestName(),
680681
min,
@@ -684,7 +685,9 @@ public void testScalingWithTaskTimeTracking() {
684685
randomBoolean(),
685686
EsExecutors.daemonThreadFactory("test"),
686687
threadContext,
687-
new EsExecutors.TaskTrackingConfig(randomBoolean(), randomDoubleBetween(0.01, 0.1, true))
688+
randomBoolean()
689+
? EsExecutors.TaskTrackingConfig.builder().trackOngoingTasks().trackExecutionTime(executionTimeEwma).build()
690+
: EsExecutors.TaskTrackingConfig.builder().trackExecutionTime(executionTimeEwma).build()
688691
);
689692
assertThat(pool, instanceOf(TaskExecutionTimeTrackingEsThreadPoolExecutor.class));
690693
}

server/src/test/java/org/elasticsearch/common/util/concurrent/TaskExecutionTimeTrackingEsThreadPoolExecutorTests.java

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
import org.elasticsearch.common.metrics.ExponentialBucketHistogram;
1313
import org.elasticsearch.common.settings.Settings;
14-
import org.elasticsearch.common.util.concurrent.EsExecutors.TaskTrackingConfig;
1514
import org.elasticsearch.telemetry.InstrumentType;
1615
import org.elasticsearch.telemetry.Measurement;
1716
import org.elasticsearch.telemetry.RecordingMeterRegistry;
@@ -51,7 +50,12 @@ public void testExecutionEWMACalculation() throws Exception {
5150
EsExecutors.daemonThreadFactory("queuetest"),
5251
new EsAbortPolicy(),
5352
context,
54-
new TaskTrackingConfig(randomBoolean(), DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST)
53+
randomBoolean()
54+
? EsExecutors.TaskTrackingConfig.builder()
55+
.trackOngoingTasks()
56+
.trackExecutionTime(DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST)
57+
.build()
58+
: EsExecutors.TaskTrackingConfig.builder().trackExecutionTime(DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST).build()
5559
);
5660
executor.prestartAllCoreThreads();
5761
logger.info("--> executor: {}", executor);
@@ -109,7 +113,16 @@ public void testMaxQueueLatency() throws Exception {
109113
EsExecutors.daemonThreadFactory("queue-latency-test"),
110114
new EsAbortPolicy(),
111115
context,
112-
new TaskTrackingConfig(randomBoolean(), true, DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST)
116+
randomBoolean()
117+
? EsExecutors.TaskTrackingConfig.builder()
118+
.trackOngoingTasks()
119+
.trackMaxQueueLatency()
120+
.trackExecutionTime(DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST)
121+
.build()
122+
: EsExecutors.TaskTrackingConfig.builder()
123+
.trackMaxQueueLatency()
124+
.trackExecutionTime(DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST)
125+
.build()
113126
);
114127
try {
115128
executor.prestartAllCoreThreads();
@@ -153,7 +166,12 @@ public void testExceptionThrowingTask() throws Exception {
153166
EsExecutors.daemonThreadFactory("queuetest"),
154167
new EsAbortPolicy(),
155168
context,
156-
new TaskTrackingConfig(randomBoolean(), DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST)
169+
randomBoolean()
170+
? EsExecutors.TaskTrackingConfig.builder()
171+
.trackOngoingTasks()
172+
.trackExecutionTime(DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST)
173+
.build()
174+
: EsExecutors.TaskTrackingConfig.builder().trackExecutionTime(DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST).build()
157175
);
158176
executor.prestartAllCoreThreads();
159177
logger.info("--> executor: {}", executor);
@@ -185,7 +203,10 @@ public void testGetOngoingTasks() throws Exception {
185203
EsExecutors.daemonThreadFactory("queuetest"),
186204
new EsAbortPolicy(),
187205
context,
188-
new TaskTrackingConfig(true, DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST)
206+
EsExecutors.TaskTrackingConfig.builder()
207+
.trackOngoingTasks()
208+
.trackExecutionTime(DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST)
209+
.build()
189210
);
190211
var taskRunningLatch = new CountDownLatch(1);
191212
var exitTaskLatch = new CountDownLatch(1);
@@ -220,7 +241,10 @@ public void testQueueLatencyHistogramMetrics() {
220241
EsExecutors.daemonThreadFactory("queuetest"),
221242
new EsAbortPolicy(),
222243
new ThreadContext(Settings.EMPTY),
223-
new TaskTrackingConfig(true, DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST)
244+
EsExecutors.TaskTrackingConfig.builder()
245+
.trackOngoingTasks()
246+
.trackExecutionTime(DEFAULT_EXECUTION_TIME_EWMA_ALPHA_FOR_TEST)
247+
.build()
224248
);
225249
executor.setupMetrics(meterRegistry, threadPoolName);
226250

0 commit comments

Comments
 (0)