diff --git a/server/src/main/java/org/elasticsearch/action/search/AbstractSearchAsyncAction.java b/server/src/main/java/org/elasticsearch/action/search/AbstractSearchAsyncAction.java
index 73e6a0306247d..f1d612cd0fe85 100644
--- a/server/src/main/java/org/elasticsearch/action/search/AbstractSearchAsyncAction.java
+++ b/server/src/main/java/org/elasticsearch/action/search/AbstractSearchAsyncAction.java
@@ -769,7 +769,7 @@ public final void execute(Runnable command) {
* tiebreak results with identical sort values
*/
protected final ShardSearchRequest buildShardSearchRequest(SearchShardIterator shardIt, int shardIndex) {
- AliasFilter filter = aliasFilter.get(shardIt.shardId().getIndex().getUUID());
+ AliasFilter filter = aliasFilter.getOrDefault(shardIt.shardId().getIndex().getUUID(), AliasFilter.EMPTY);
assert filter != null;
float indexBoost = concreteIndexBoosts.getOrDefault(shardIt.shardId().getIndex().getUUID(), DEFAULT_INDEX_BOOST);
ShardSearchRequest shardRequest = new ShardSearchRequest(
diff --git a/server/src/main/java/org/elasticsearch/action/search/CanMatchPreFilterSearchPhase.java b/server/src/main/java/org/elasticsearch/action/search/CanMatchPreFilterSearchPhase.java
index d45a8a6f01cd1..6a2b7037ce553 100644
--- a/server/src/main/java/org/elasticsearch/action/search/CanMatchPreFilterSearchPhase.java
+++ b/server/src/main/java/org/elasticsearch/action/search/CanMatchPreFilterSearchPhase.java
@@ -376,16 +376,13 @@ private void finishPhase() {
private static final float DEFAULT_INDEX_BOOST = 1.0f;
public CanMatchNodeRequest.Shard buildShardLevelRequest(SearchShardIterator shardIt) {
- AliasFilter filter = aliasFilter.get(shardIt.shardId().getIndex().getUUID());
- assert filter != null;
- float indexBoost = concreteIndexBoosts.getOrDefault(shardIt.shardId().getIndex().getUUID(), DEFAULT_INDEX_BOOST);
int shardRequestIndex = shardItIndexMap.get(shardIt);
return new CanMatchNodeRequest.Shard(
shardIt.getOriginalIndices().indices(),
shardIt.shardId(),
shardRequestIndex,
- filter,
- indexBoost,
+ aliasFilter.getOrDefault(shardIt.shardId().getIndex().getUUID(), AliasFilter.EMPTY),
+ concreteIndexBoosts.getOrDefault(shardIt.shardId().getIndex().getUUID(), DEFAULT_INDEX_BOOST),
shardIt.getSearchContextId(),
shardIt.getSearchContextKeepAlive(),
ShardSearchRequest.computeWaitForCheckpoint(request.getWaitForCheckpoints(), shardIt.shardId(), shardRequestIndex)
diff --git a/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java b/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java
index 70a7f4c8cad0c..936ea1a3359fb 100644
--- a/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java
+++ b/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java
@@ -259,14 +259,17 @@ private static boolean hasDataStreamRef(ClusterState clusterState, Set i
Map buildIndexAliasFilters(
ClusterState clusterState,
Set indicesAndAliases,
- Index[] concreteIndices
+ Index[] concreteIndices,
+ boolean filterEmpty
) {
final Map aliasFilterMap = new HashMap<>();
for (Index index : concreteIndices) {
clusterState.blocks().indexBlockedRaiseException(ClusterBlockLevel.READ, index.getName());
AliasFilter aliasFilter = searchService.buildAliasFilter(clusterState, index.getName(), indicesAndAliases);
assert aliasFilter != null;
- aliasFilterMap.put(index.getUUID(), aliasFilter);
+ if (filterEmpty == false || aliasFilter != AliasFilter.EMPTY) {
+ aliasFilterMap.put(index.getUUID(), aliasFilter);
+ }
}
return aliasFilterMap;
}
@@ -1087,7 +1090,7 @@ static List getRemoteShardsIterator(
// add the cluster name to the remote index names for indices disambiguation
// this ends up in the hits returned with the search response
ShardId shardId = searchShardsGroup.shardId();
- AliasFilter aliasFilter = aliasFilterMap.get(shardId.getIndex().getUUID());
+ AliasFilter aliasFilter = aliasFilterMap.getOrDefault(shardId.getIndex().getUUID(), AliasFilter.EMPTY);
String[] aliases = aliasFilter.getAliases();
String clusterAlias = entry.getKey();
String[] finalIndices = aliases.length == 0 ? new String[] { shardId.getIndexName() } : aliases;
@@ -1247,7 +1250,7 @@ private void executeSearch(
clusterState,
searchRequest.indices()
);
- aliasFilter = buildIndexAliasFilters(clusterState, indicesAndAliases, indices);
+ aliasFilter = buildIndexAliasFilters(clusterState, indicesAndAliases, indices, true);
aliasFilter.putAll(remoteAliasMap);
localShardIterators = getLocalShardsIterator(
clusterState,
diff --git a/server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java b/server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java
index 614a3e9cf22ae..e81155f52b891 100644
--- a/server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java
+++ b/server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java
@@ -135,7 +135,8 @@ public void searchShards(Task task, SearchShardsRequest searchShardsRequest, Act
final Map aliasFilters = transportSearchAction.buildIndexAliasFilters(
clusterState,
indicesAndAliases,
- concreteIndices
+ concreteIndices,
+ false
);
String[] concreteIndexNames = Arrays.stream(concreteIndices).map(Index::getName).toArray(String[]::new);
GroupShardsIterator shardIts = GroupShardsIterator.sortAndCreate(
diff --git a/server/src/main/java/org/elasticsearch/indices/IndicesService.java b/server/src/main/java/org/elasticsearch/indices/IndicesService.java
index 0a3baf2c52f57..4468250e34942 100644
--- a/server/src/main/java/org/elasticsearch/indices/IndicesService.java
+++ b/server/src/main/java/org/elasticsearch/indices/IndicesService.java
@@ -34,11 +34,9 @@
import org.elasticsearch.client.internal.Client;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.DataStream;
-import org.elasticsearch.cluster.metadata.IndexAbstraction;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
-import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.routing.RecoverySource;
import org.elasticsearch.cluster.routing.ShardRouting;
@@ -49,6 +47,7 @@
import org.elasticsearch.common.breaker.CircuitBreaker;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
+import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.io.FileSystemUtils;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput;
@@ -1717,52 +1716,56 @@ interface IndexDeletionAllowedPredicate {
private final IndexDeletionAllowedPredicate ALWAYS_TRUE = (Index index, IndexSettings indexSettings) -> true;
public AliasFilter buildAliasFilter(ClusterState state, String index, Set resolvedExpressions) {
- /* Being static, parseAliasFilter doesn't have access to whatever guts it needs to parse a query. Instead of passing in a bunch
- * of dependencies we pass in a function that can perform the parsing. */
- CheckedFunction filterParser = bytes -> {
- try (
- XContentParser parser = XContentHelper.createParserNotCompressed(parserConfig, bytes, XContentHelper.xContentType(bytes))
- ) {
- return parseTopLevelQuery(parser);
- }
- };
String[] aliases = indexNameExpressionResolver.filteringAliases(state, index, resolvedExpressions);
if (aliases == null) {
return AliasFilter.EMPTY;
}
- Metadata metadata = state.metadata();
- IndexAbstraction ia = state.metadata().getIndicesLookup().get(index);
- DataStream dataStream = ia.getParentDataStream();
- if (dataStream != null) {
- String dataStreamName = dataStream.getName();
- List filters = Arrays.stream(aliases)
- .map(name -> metadata.dataStreamAliases().get(name))
- .filter(dataStreamAlias -> dataStreamAlias.getFilter(dataStreamName) != null)
- .map(dataStreamAlias -> {
- try {
- return filterParser.apply(dataStreamAlias.getFilter(dataStreamName).uncompressed());
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- })
- .toList();
- if (filters.isEmpty()) {
- return AliasFilter.of(null, aliases);
- } else {
- if (filters.size() == 1) {
- return AliasFilter.of(filters.get(0), aliases);
- } else {
- BoolQueryBuilder bool = new BoolQueryBuilder();
- for (QueryBuilder filter : filters) {
- bool.should(filter);
- }
- return AliasFilter.of(bool, aliases);
+ return doBuildAliasFilter(state, index, aliases);
+ }
+
+ private AliasFilter doBuildAliasFilter(ClusterState state, String index, String[] aliases) {
+ DataStream dataStream = state.metadata().getIndicesLookup().get(index).getParentDataStream();
+ if (dataStream == null) {
+ return AliasFilter.of(ShardSearchRequest.parseAliasFilter(this::parseFilter, state.metadata().index(index), aliases), aliases);
+ }
+ var dataStreamAliases = state.metadata().dataStreamAliases();
+ String dataStreamName = dataStream.getName();
+ List filters = Arrays.stream(aliases)
+ .map(dataStreamAliases::get)
+ .filter(dataStreamAlias -> dataStreamAlias.getFilter(dataStreamName) != null)
+ .map(dataStreamAlias -> {
+ try {
+ return parseFilter(dataStreamAlias.getFilter(dataStreamName));
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
- }
- } else {
- IndexMetadata indexMetadata = metadata.index(index);
- return AliasFilter.of(ShardSearchRequest.parseAliasFilter(filterParser, indexMetadata, aliases), aliases);
+ })
+ .toList();
+
+ if (filters.isEmpty()) {
+ return AliasFilter.of(null, aliases);
+ }
+ if (filters.size() == 1) {
+ return AliasFilter.of(filters.get(0), aliases);
+ }
+ BoolQueryBuilder bool = new BoolQueryBuilder();
+ for (QueryBuilder filter : filters) {
+ bool.should(filter);
+ }
+ return AliasFilter.of(bool, aliases);
+ }
+
+ private QueryBuilder parseFilter(CompressedXContent bytes) throws IOException {
+ var uncompressed = bytes.uncompressed();
+ try (
+ XContentParser parser = XContentHelper.createParserNotCompressed(
+ parserConfig,
+ uncompressed,
+ XContentHelper.xContentType(uncompressed)
+ )
+ ) {
+ return parseTopLevelQuery(parser);
}
}
diff --git a/server/src/main/java/org/elasticsearch/search/internal/ShardSearchRequest.java b/server/src/main/java/org/elasticsearch/search/internal/ShardSearchRequest.java
index 5e4ffbdba9ad2..97c4d81210090 100644
--- a/server/src/main/java/org/elasticsearch/search/internal/ShardSearchRequest.java
+++ b/server/src/main/java/org/elasticsearch/search/internal/ShardSearchRequest.java
@@ -23,6 +23,7 @@
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
+import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.hash.MessageDigests;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
@@ -621,7 +622,7 @@ public Rewriteable rewrite(QueryRewriteContext ctx) throws IOException {
* Returns {@code null} if no filtering is required.
*/
public static QueryBuilder parseAliasFilter(
- CheckedFunction filterParser,
+ CheckedFunction filterParser,
IndexMetadata metadata,
String... aliasNames
) {
@@ -635,7 +636,7 @@ public static QueryBuilder parseAliasFilter(
return null;
}
try {
- return filterParser.apply(alias.filter().uncompressed());
+ return filterParser.apply(alias.filter());
} catch (IOException ex) {
throw new AliasFilterParsingException(index, alias.getAlias(), "Invalid alias filter", ex);
}
diff --git a/server/src/test/java/org/elasticsearch/search/internal/ShardSearchRequestTests.java b/server/src/test/java/org/elasticsearch/search/internal/ShardSearchRequestTests.java
index 5ff6e04648c87..a4f4861b05d63 100644
--- a/server/src/test/java/org/elasticsearch/search/internal/ShardSearchRequestTests.java
+++ b/server/src/test/java/org/elasticsearch/search/internal/ShardSearchRequestTests.java
@@ -210,7 +210,7 @@ private IndexMetadata add(IndexMetadata indexMetadata, String alias, @Nullable C
public QueryBuilder aliasFilter(IndexMetadata indexMetadata, String... aliasNames) {
return ShardSearchRequest.parseAliasFilter(bytes -> {
try (
- InputStream inputStream = bytes.streamInput();
+ InputStream inputStream = bytes.uncompressed().streamInput();
XContentParser parser = XContentFactory.xContentType(inputStream)
.xContent()
.createParser(xContentRegistry(), DeprecationHandler.THROW_UNSUPPORTED_OPERATION, inputStream)