Skip to content

Commit 2df7f62

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents 41dcc1c + 18b281e commit 2df7f62

33 files changed

+423
-229
lines changed

docs/changelog/119580.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 119580
2+
summary: Do not serialize `EsIndex` in plan
3+
area: ES|QL
4+
type: enhancement
5+
issues: []

docs/reference/mapping/types/array.asciidoc

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,16 @@ same data type. For instance:
1010
* an array of arrays: [ `1`, [ `2`, `3` ]] which is the equivalent of [ `1`, `2`, `3` ]
1111
* an array of objects: [ `{ "name": "Mary", "age": 12 }`, `{ "name": "John", "age": 10 }`]
1212

13-
.Arrays of objects
13+
.Arrays with `object` field type vs `nested` type
1414
[NOTE]
1515
====================================================
1616
17-
Arrays of objects do not work as you would expect: you cannot query each
18-
object independently of the other objects in the array. If you need to be
19-
able to do this then you should use the <<nested,`nested`>> data type instead
20-
of the <<object,`object`>> data type.
17+
Arrays of objects in Elasticsearch do not behave as you would expect: queries may match fields across different objects in the array, leading to unexpected results. By default, arrays of objects are <<nested-arrays-flattening-objects,flattened>>
18+
during indexing. To ensure queries match values within the same object, use the <<nested,`nested`>> data type instead of the <<object,`object`>> data type.
2119
22-
This is explained in more detail in <<nested>>.
20+
This behavior is explained in more detail in <<nested-arrays-flattening-objects, `nested`>>.
2321
====================================================
2422

25-
2623
When adding a field dynamically, the first value in the array determines the
2724
field `type`. All subsequent values must be of the same data type or it must
2825
at least be possible to <<coerce,coerce>> subsequent values to the same
@@ -81,3 +78,10 @@ GET my-index-000001/_search
8178
<3> The second document contains no arrays, but can be indexed into the same fields.
8279
<4> The query looks for `elasticsearch` in the `tags` field, and matches both documents.
8380

81+
[TIP]
82+
====
83+
You can modify arrays using the <<update-api-example,update API>>.
84+
====
85+
86+
87+

docs/reference/query-dsl/wildcard-query.asciidoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ the iterations needed to find matching terms and slow search performance.
8181

8282
[[wildcard-query-notes]]
8383
==== Notes
84+
85+
Wildcard queries using `*` can be resource-intensive, particularly with leading wildcards. To improve performance, minimize their use and consider alternatives like the <<analysis-ngram-tokenizer,n-gram tokenizer>>. While this allows for more efficient searching, it may increase index size. For better performance and accuracy, combine wildcard queries with other query types like <<query-dsl-match-query,`match`>> or <<query-dsl-bool-query,`bool`>> to first narrow down results.
86+
8487
===== Allow expensive queries
8588
Wildcard queries will not be executed if <<query-dsl-allow-expensive-queries, `search.allow_expensive_queries`>>
8689
is set to false.

muted-tests.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ tests:
252252
- class: org.elasticsearch.reservedstate.service.FileSettingsServiceTests
253253
method: testInvalidJSON
254254
issue: https://github.com/elastic/elasticsearch/issues/120482
255+
- class: org.elasticsearch.smoketest.DocsClientYamlTestSuiteIT
256+
issue: https://github.com/elastic/elasticsearch/issues/120497
255257

256258
# Examples:
257259
#

server/src/main/java/org/elasticsearch/TransportVersions.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ static TransportVersion def(int id) {
158158
public static final TransportVersion ESQL_PROFILE_ROWS_PROCESSED = def(8_824_00_0);
159159
public static final TransportVersion BYTE_SIZE_VALUE_ALWAYS_USES_BYTES_1 = def(8_825_00_0);
160160
public static final TransportVersion REVERT_BYTE_SIZE_VALUE_ALWAYS_USES_BYTES_1 = def(8_826_00_0);
161+
public static final TransportVersion ESQL_SKIP_ES_INDEX_SERIALIZATION = def(8_827_00_0);
161162

162163
/*
163164
* STOP! READ THIS FIRST! No, really,

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

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
package org.elasticsearch.action.search;
1111

1212
import org.apache.logging.log4j.Logger;
13-
import org.apache.lucene.util.CollectionUtil;
1413
import org.apache.lucene.util.SetOnce;
1514
import org.elasticsearch.ElasticsearchException;
1615
import org.elasticsearch.ExceptionsHelper;
@@ -26,6 +25,7 @@
2625
import org.elasticsearch.cluster.routing.GroupShardsIterator;
2726
import org.elasticsearch.common.bytes.BytesReference;
2827
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
28+
import org.elasticsearch.common.util.Maps;
2929
import org.elasticsearch.common.util.concurrent.AtomicArray;
3030
import org.elasticsearch.core.Releasable;
3131
import org.elasticsearch.core.Releasables;
@@ -43,8 +43,7 @@
4343
import org.elasticsearch.transport.Transport;
4444

4545
import java.util.ArrayList;
46-
import java.util.Collections;
47-
import java.util.HashMap;
46+
import java.util.Arrays;
4847
import java.util.List;
4948
import java.util.Map;
5049
import java.util.concurrent.ConcurrentHashMap;
@@ -98,7 +97,6 @@ abstract class AbstractSearchAsyncAction<Result extends SearchPhaseResult> exten
9897
protected final GroupShardsIterator<SearchShardIterator> toSkipShardsIts;
9998
protected final GroupShardsIterator<SearchShardIterator> shardsIts;
10099
private final SearchShardIterator[] shardIterators;
101-
private final Map<SearchShardIterator, Integer> shardIndexMap;
102100
private final int expectedTotalOps;
103101
private final AtomicInteger totalOps = new AtomicInteger();
104102
private final int maxConcurrentRequestsPerNode;
@@ -142,17 +140,11 @@ abstract class AbstractSearchAsyncAction<Result extends SearchPhaseResult> exten
142140
this.toSkipShardsIts = new GroupShardsIterator<>(toSkipIterators);
143141
this.shardsIts = new GroupShardsIterator<>(iterators);
144142

145-
// we compute the shard index based on the natural order of the shards
143+
this.shardIterators = iterators.toArray(new SearchShardIterator[0]);
144+
// we later compute the shard index based on the natural order of the shards
146145
// that participate in the search request. This means that this number is
147146
// consistent between two requests that target the same shards.
148-
Map<SearchShardIterator, Integer> shardMap = new HashMap<>();
149-
List<SearchShardIterator> searchIterators = new ArrayList<>(iterators);
150-
CollectionUtil.timSort(searchIterators);
151-
for (int i = 0; i < searchIterators.size(); i++) {
152-
shardMap.put(searchIterators.get(i), i);
153-
}
154-
this.shardIndexMap = Collections.unmodifiableMap(shardMap);
155-
this.shardIterators = searchIterators.toArray(SearchShardIterator[]::new);
147+
Arrays.sort(shardIterators);
156148

157149
// we need to add 1 for non active partition, since we count it in the total. This means for each shard in the iterator we sum up
158150
// it's number of active shards but use 1 as the default if no replica of a shard is active at this point.
@@ -236,6 +228,10 @@ protected final void run() {
236228
assert iterator.skip();
237229
skipShard(iterator);
238230
}
231+
final Map<SearchShardIterator, Integer> shardIndexMap = Maps.newHashMapWithExpectedSize(shardIterators.length);
232+
for (int i = 0; i < shardIterators.length; i++) {
233+
shardIndexMap.put(shardIterators[i], i);
234+
}
239235
if (shardsIts.size() > 0) {
240236
doCheckNoMissingShards(getName(), request, shardsIts);
241237
for (int i = 0; i < shardsIts.size(); i++) {

x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public static Range rangeOf(Expression value, Expression lower, boolean includeL
215215
}
216216

217217
public static EsRelation relation() {
218-
return new EsRelation(EMPTY, new EsIndex(randomAlphaOfLength(8), emptyMap()), IndexMode.STANDARD, randomBoolean());
218+
return new EsRelation(EMPTY, new EsIndex(randomAlphaOfLength(8), emptyMap()), IndexMode.STANDARD);
219219
}
220220

221221
/**

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,13 @@ private LogicalPlan resolveIndex(UnresolvedRelation plan, IndexResolution indexR
269269
}
270270
var attributes = mappingAsAttributes(plan.source(), esIndex.mapping());
271271
attributes.addAll(plan.metadataFields());
272-
return new EsRelation(plan.source(), esIndex, attributes.isEmpty() ? NO_FIELDS : attributes, plan.indexMode());
272+
return new EsRelation(
273+
plan.source(),
274+
esIndex.name(),
275+
plan.indexMode(),
276+
esIndex.indexNameWithModes(),
277+
attributes.isEmpty() ? NO_FIELDS : attributes
278+
);
273279
}
274280
}
275281

@@ -1371,9 +1377,13 @@ private LogicalPlan doRule(LogicalPlan plan) {
13711377
}
13721378

13731379
if (missing.isEmpty() == false) {
1374-
List<Attribute> newOutput = new ArrayList<>(esr.output());
1375-
newOutput.addAll(missing);
1376-
return new EsRelation(esr.source(), esr.index(), newOutput, esr.indexMode(), esr.frozen());
1380+
return new EsRelation(
1381+
esr.source(),
1382+
esr.indexPattern(),
1383+
esr.indexMode(),
1384+
esr.indexNameWithModes(),
1385+
CollectionUtils.combine(esr.output(), missing)
1386+
);
13771387
}
13781388
return esr;
13791389
});

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PruneColumns.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,13 @@ public LogicalPlan apply(LogicalPlan plan) {
102102
p = new Eval(eval.source(), eval.child(), remaining);
103103
}
104104
}
105-
} else if (p instanceof EsRelation esRelation && esRelation.indexMode() == IndexMode.LOOKUP) {
105+
} else if (p instanceof EsRelation esr && esr.indexMode() == IndexMode.LOOKUP) {
106106
// Normally, pruning EsRelation has no effect because InsertFieldExtraction only extracts the required fields, anyway.
107107
// However, InsertFieldExtraction can't be currently used in LOOKUP JOIN right index,
108108
// it works differently as we extract all fields (other than the join key) that the EsRelation has.
109-
var remaining = removeUnused(esRelation.output(), used);
109+
var remaining = removeUnused(esr.output(), used);
110110
if (remaining != null) {
111-
p = new EsRelation(esRelation.source(), esRelation.index(), remaining, esRelation.indexMode(), esRelation.frozen());
111+
p = new EsRelation(esr.source(), esr.indexPattern(), esr.indexMode(), esr.indexNameWithModes(), remaining);
112112
}
113113
}
114114
} while (recheck);

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/SkipQueryOnEmptyMappings.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ public final class SkipQueryOnEmptyMappings extends OptimizerRules.OptimizerRule
1616

1717
@Override
1818
protected LogicalPlan rule(EsRelation plan) {
19-
return plan.index().concreteIndices().isEmpty() ? new LocalRelation(plan.source(), plan.output(), LocalSupplier.EMPTY) : plan;
19+
return plan.concreteIndices().isEmpty() ? new LocalRelation(plan.source(), plan.output(), LocalSupplier.EMPTY) : plan;
2020
}
2121
}

0 commit comments

Comments
 (0)