Skip to content

Commit e6c060b

Browse files
authored
Merge branch 'main' into enhancement/126526
2 parents fa08ea6 + 591fa87 commit e6c060b

File tree

54 files changed

+2320
-841
lines changed

Some content is hidden

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

54 files changed

+2320
-841
lines changed

docs/changelog/126385.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 126385
2+
summary: Filter out empty top docs results before merging
3+
area: Search
4+
type: bug
5+
issues:
6+
- 126118

docs/changelog/126550.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 126550
2+
summary: Add leniency to missing array values in mustache
3+
area: Infra/Scripting
4+
type: bug
5+
issues:
6+
- 55200

docs/release-notes/index.md

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,25 @@ To check for security updates, go to [Security announcements for the Elastic sta
2525

2626
### Highlights [elasticsearch-900-highlights]
2727

28-
::::{dropdown} Add new experimental `rank_vectors` mapping for late-interaction second order ranking
29-
Late-interaction models are powerful rerankers. While their size and overall cost doesn't lend itself for HNSW indexing, utilizing them as second order reranking can provide excellent boosts in relevance. The new `rank_vectors` mapping allows for rescoring over new and novel multi-vector late-interaction models like ColBERT or ColPali.
28+
::::{dropdown} rank_vectors field type is now available for late-interaction ranking
3029

31-
For more information, check [PR #118804](https://github.com/elastic/elasticsearch/pull/118804).
32-
::::
30+
[`rank_vectors`](../reference/elasticsearch/mapping-reference/rank-vectors.md) is a new field type released as an experimental feature in Elasticsearch 9.0. It is designed to be used with dense vectors and allows for late-interaction second order ranking.
3331

34-
::::{dropdown} Enable LOOKUP JOIN in non-snapshot builds
35-
This effectively releases LOOKUP JOIN into tech preview. Docs will
36-
follow in a separate PR.
32+
Late-interaction models are powerful rerankers. While their size and overall cost doesn’t lend itself for HNSW indexing, utilizing them as second order reranking can provide excellent boosts in relevance. The new `rank_vectors` mapping allows for rescoring over new and novel multi-vector late-interaction models like ColBERT or ColPali.
33+
::::
3734

38-
- Enable the lexing/grammar for LOOKUP JOIN in non-snapshot builds.
39-
- Remove the grammar for the unsupported `| JOIN ...` command (without `LOOKUP` as first keyword). The way the lexer modes work, otherwise we'd also have to enable `| JOIN ...` syntax on non-snapshot builds and would have to add additional validation to provide appropriate error messages.
40-
- Remove grammar for `LOOKUP JOIN index AS ...` because qualifiers are not yet supported. Otherwise we'd have to put in additional validation as well to prevent such queries.
35+
::::{dropdown} ES|QL LOOKUP JOIN is now available in technical preview
4136

42-
Also fix https://github.com/elastic/elasticsearch/issues/121185
37+
[LOOKUP JOIN](../reference/query-languages/esql/esql-commands.md) is now available in technical preview. LOOKUP JOIN combines data from your ES|QL queries with matching records from a lookup index, enabling you to:
4338

44-
For more information, check [PR #121193](https://github.com/elastic/elasticsearch/pull/121193).
39+
- Enrich your search results with reference data
40+
- Speed up root-cause analysis and security investigations
41+
- Join data across indices without complex queries
42+
- Reduce operational overhead when correlating events
4543
::::
4644

47-
::::{dropdown} Release semantic_text as a GA feature
48-
semantic_text is now an official GA (generally available) feature! This field type allows you to easily set up and perform semantic search with minimal ramp up time.
49-
50-
For more information, check [PR #124669](https://github.com/elastic/elasticsearch/pull/124669).
45+
::::{dropdown} The semantic_text field type is now GA
46+
[`semantic_text`](../reference/elasticsearch/mapping-reference/semantic-text.md) is now an official GA (generally available) feature! This field type allows you to easily set up and perform semantic search with minimal ramp up time.
5147
::::
5248

5349
### Features and enhancements [elasticsearch-900-features-enhancements]

modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/CustomReflectionObjectHandler.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,11 @@ public Object get(Object key) {
111111
if ("size".equals(key)) {
112112
return size();
113113
} else if (key instanceof Number number) {
114-
return Array.get(array, number.intValue());
114+
return number.intValue() >= 0 && number.intValue() < length ? Array.get(array, number.intValue()) : null;
115115
}
116116
try {
117117
int index = Integer.parseInt(key.toString());
118-
return Array.get(array, index);
118+
return index >= 0 && index < length ? Array.get(array, index) : null;
119119
} catch (NumberFormatException nfe) {
120120
// if it's not a number it is as if the key doesn't exist
121121
return null;
@@ -169,11 +169,11 @@ public Object get(Object key) {
169169
if ("size".equals(key)) {
170170
return col.size();
171171
} else if (key instanceof Number number) {
172-
return Iterables.get(col, number.intValue());
172+
return number.intValue() >= 0 && number.intValue() < col.size() ? Iterables.get(col, number.intValue()) : null;
173173
}
174174
try {
175175
int index = Integer.parseInt(key.toString());
176-
return Iterables.get(col, index);
176+
return index >= 0 && index < col.size() ? Iterables.get(col, index) : null;
177177
} catch (NumberFormatException nfe) {
178178
// if it's not a number it is as if the key doesn't exist
179179
return null;

modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/MustacheTests.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,26 @@ public void testMapInArrayAccess() throws Exception {
141141
assertThat(output, both(containsString("foo")).and(containsString("bar")));
142142
}
143143

144+
public void testMapInArrayBadAccess() throws Exception {
145+
String template = "{{data.0.key}} {{data.2.key}}";
146+
TemplateScript.Factory factory = engine.compile(null, template, TemplateScript.CONTEXT, Collections.emptyMap());
147+
Map<String, Object> vars = new HashMap<>();
148+
vars.put("data", new Object[] { singletonMap("key", "foo"), singletonMap("key", "bar") });
149+
// assertThat(factory.newInstance(vars).execute(), equalTo("foo "));
150+
151+
vars.put("data", Arrays.asList(singletonMap("key", "foo"), singletonMap("key", "bar")));
152+
factory.newInstance(vars);
153+
assertThat(factory.newInstance(vars).execute(), equalTo("foo "));
154+
155+
// HashSet iteration order isn't fixed
156+
Set<Object> setData = new HashSet<>();
157+
setData.add(singletonMap("key", "foo"));
158+
setData.add(singletonMap("key", "bar"));
159+
vars.put("data", setData);
160+
String output = factory.newInstance(vars).execute();
161+
assertThat(output, both(containsString("foo")).and(not(containsString("bar"))));
162+
}
163+
144164
public void testSizeAccessForCollectionsAndArrays() throws Exception {
145165
String[] randomArrayValues = generateRandomStringArray(10, 20, false);
146166
List<String> randomList = Arrays.asList(generateRandomStringArray(10, 20, false));

muted-tests.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,18 @@ tests:
423423
- class: org.elasticsearch.smoketest.MlWithSecurityIT
424424
method: test {yaml=ml/get_trained_model_stats/Test get stats given trained models}
425425
issue: https://github.com/elastic/elasticsearch/issues/126510
426+
- class: org.elasticsearch.xpack.test.rest.XPackRestIT
427+
method: test {p0=transform/transforms_stats/Test get multiple transform stats}
428+
issue: https://github.com/elastic/elasticsearch/issues/126567
429+
- class: org.elasticsearch.xpack.test.rest.XPackRestIT
430+
method: test {p0=transform/transforms_stats/Test get single transform stats when it does not have a task}
431+
issue: https://github.com/elastic/elasticsearch/issues/126568
432+
- class: org.elasticsearch.repositories.blobstore.testkit.rest.SnapshotRepoTestKitClientYamlTestSuiteIT
433+
method: test {p0=/10_analyze/Analysis without details}
434+
issue: https://github.com/elastic/elasticsearch/issues/126569
435+
- class: org.elasticsearch.repositories.blobstore.testkit.analyze.S3RepositoryAnalysisRestIT
436+
method: testRepositoryAnalysis
437+
issue: https://github.com/elastic/elasticsearch/issues/126576
426438

427439
# Examples:
428440
#

server/src/internalClusterTest/java/org/elasticsearch/index/shard/IndexShardIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ public void testInvalidateIndicesRequestCacheWhenRollbackEngine() throws Excepti
676676
final CountDownLatch engineResetLatch = new CountDownLatch(1);
677677
shard.acquireAllPrimaryOperationsPermits(ActionListener.wrap(r -> {
678678
try {
679-
shard.resetEngineToGlobalCheckpoint();
679+
shard.rollbackEngineToGlobalCheckpoint();
680680
} finally {
681681
r.close();
682682
engineResetLatch.countDown();

server/src/internalClusterTest/java/org/elasticsearch/indices/IndexingMemoryControllerIT.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ EngineConfig engineConfigWithLargerIndexingMemory(EngineConfig config) {
8484
config.getRelativeTimeInNanosSupplier(),
8585
config.getIndexCommitListener(),
8686
config.isPromotableToPrimary(),
87-
config.getMapperService()
87+
config.getMapperService(),
88+
config.getEngineResetLock()
8889
);
8990
}
9091

server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ public void testDeletionOfFailingToRecoverIndexShouldStopRestore() throws Except
748748

749749
logger.info("--> wait for the index to appear");
750750
// that would mean that recovery process started and failing
751-
safeGet(clusterAdmin().prepareHealth(SAFE_AWAIT_TIMEOUT, "test-idx").execute());
751+
awaitIndexExists("test-idx");
752752

753753
logger.info("--> delete index");
754754
cluster().wipeIndices("test-idx");

server/src/main/java/org/elasticsearch/action/search/SearchPhaseController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,11 @@ static TopDocs mergeTopDocs(List<TopDocs> results, int topN, int from) {
150150
return topDocs;
151151
} else if (topDocs instanceof TopFieldGroups firstTopDocs) {
152152
final Sort sort = new Sort(firstTopDocs.fields);
153-
final TopFieldGroups[] shardTopDocs = results.toArray(new TopFieldGroups[0]);
153+
final TopFieldGroups[] shardTopDocs = results.stream().filter(td -> td != Lucene.EMPTY_TOP_DOCS).toArray(TopFieldGroups[]::new);
154154
mergedTopDocs = TopFieldGroups.merge(sort, from, topN, shardTopDocs, false);
155155
} else if (topDocs instanceof TopFieldDocs firstTopDocs) {
156156
final Sort sort = checkSameSortTypes(results, firstTopDocs.fields);
157-
final TopFieldDocs[] shardTopDocs = results.toArray(new TopFieldDocs[0]);
157+
final TopFieldDocs[] shardTopDocs = results.stream().filter((td -> td != Lucene.EMPTY_TOP_DOCS)).toArray(TopFieldDocs[]::new);
158158
mergedTopDocs = TopDocs.merge(sort, from, topN, shardTopDocs);
159159
} else {
160160
final TopDocs[] shardTopDocs = results.toArray(new TopDocs[numShards]);

0 commit comments

Comments
 (0)