From 4a777afb3770520126bb05336c0afe795ec067a9 Mon Sep 17 00:00:00 2001 From: tlrx Date: Thu, 6 Nov 2025 10:51:23 +0100 Subject: [PATCH 1/2] Add IdLoader.create method --- .../elasticsearch/index/mapper/IdLoader.java | 37 +++++++++++++++++++ .../search/DefaultSearchContext.java | 33 +---------------- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/index/mapper/IdLoader.java b/server/src/main/java/org/elasticsearch/index/mapper/IdLoader.java index 30407f8b4645f..6ed8628d051db 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/IdLoader.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/IdLoader.java @@ -18,16 +18,53 @@ import org.elasticsearch.cluster.metadata.DataStream; import org.elasticsearch.cluster.routing.IndexRouting; import org.elasticsearch.cluster.routing.RoutingHashBuilder; +import org.elasticsearch.index.IndexMode; +import org.elasticsearch.index.IndexVersions; import org.elasticsearch.index.fieldvisitor.LeafStoredFieldLoader; import java.io.IOException; +import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.TreeSet; /** * Responsible for loading the _id from stored fields or for TSDB synthesizing the _id from the routing, _tsid and @timestamp fields. */ public sealed interface IdLoader permits IdLoader.TsIdLoader, IdLoader.StoredIdLoader { + /** + * @return returns an {@link IdLoader} instance to load the value of the _id field. + */ + static IdLoader create(MapperService mapperService) { + var indexSettings = mapperService.getIndexSettings(); + if (indexSettings.getMode() == IndexMode.TIME_SERIES) { + IndexRouting.ExtractFromSource.ForRoutingPath indexRouting = null; + List routingPaths = null; + if (indexSettings.getIndexVersionCreated().before(IndexVersions.TIME_SERIES_ROUTING_HASH_IN_ID)) { + indexRouting = (IndexRouting.ExtractFromSource.ForRoutingPath) indexSettings.getIndexRouting(); + routingPaths = indexSettings.getIndexMetadata().getRoutingPaths(); + for (String routingField : routingPaths) { + if (routingField.contains("*")) { + // In case the routing fields include path matches, find any matches and add them as distinct fields + // to the routing path. + Set matchingRoutingPaths = new TreeSet<>(routingPaths); + for (Mapper mapper : mapperService.mappingLookup().fieldMappers()) { + if (mapper instanceof KeywordFieldMapper && indexRouting.matchesField(mapper.fullPath())) { + matchingRoutingPaths.add(mapper.fullPath()); + } + } + routingPaths = new ArrayList<>(matchingRoutingPaths); + break; + } + } + } + return IdLoader.createTsIdLoader(indexRouting, routingPaths, indexSettings.useTimeSeriesSyntheticId()); + } else { + return IdLoader.fromLeafStoredFieldLoader(); + } + } + /** * @return returns an {@link IdLoader} instance the loads the _id from stored field. */ diff --git a/server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java b/server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java index 0b94b3be3650f..3e8134489f740 100644 --- a/server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java +++ b/server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java @@ -23,16 +23,13 @@ import org.apache.lucene.util.NumericUtils; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.search.SearchType; -import org.elasticsearch.cluster.routing.IndexRouting; import org.elasticsearch.common.breaker.CircuitBreaker; import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.core.Nullable; import org.elasticsearch.core.Releasables; import org.elasticsearch.core.TimeValue; -import org.elasticsearch.index.IndexMode; import org.elasticsearch.index.IndexService; import org.elasticsearch.index.IndexSettings; -import org.elasticsearch.index.IndexVersions; import org.elasticsearch.index.cache.bitset.BitsetFilterCache; import org.elasticsearch.index.engine.Engine; import org.elasticsearch.index.fielddata.FieldDataContext; @@ -40,9 +37,7 @@ import org.elasticsearch.index.fielddata.IndexNumericFieldData; import org.elasticsearch.index.fielddata.IndexOrdinalsFieldData; import org.elasticsearch.index.mapper.IdLoader; -import org.elasticsearch.index.mapper.KeywordFieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; -import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.NestedLookup; import org.elasticsearch.index.mapper.SourceLoader; import org.elasticsearch.index.query.AbstractQueryBuilder; @@ -88,8 +83,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.TreeSet; import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; import java.util.function.LongSupplier; @@ -950,30 +943,6 @@ public SourceLoader newSourceLoader(@Nullable SourceFilter filter) { @Override public IdLoader newIdLoader() { - if (indexService.getIndexSettings().getMode() == IndexMode.TIME_SERIES) { - IndexRouting.ExtractFromSource.ForRoutingPath indexRouting = null; - List routingPaths = null; - if (indexService.getIndexSettings().getIndexVersionCreated().before(IndexVersions.TIME_SERIES_ROUTING_HASH_IN_ID)) { - indexRouting = (IndexRouting.ExtractFromSource.ForRoutingPath) indexService.getIndexSettings().getIndexRouting(); - routingPaths = indexService.getMetadata().getRoutingPaths(); - for (String routingField : routingPaths) { - if (routingField.contains("*")) { - // In case the routing fields include path matches, find any matches and add them as distinct fields - // to the routing path. - Set matchingRoutingPaths = new TreeSet<>(routingPaths); - for (Mapper mapper : indexService.mapperService().mappingLookup().fieldMappers()) { - if (mapper instanceof KeywordFieldMapper && indexRouting.matchesField(mapper.fullPath())) { - matchingRoutingPaths.add(mapper.fullPath()); - } - } - routingPaths = new ArrayList<>(matchingRoutingPaths); - break; - } - } - } - return IdLoader.createTsIdLoader(indexRouting, routingPaths, indexService.getIndexSettings().useTimeSeriesSyntheticId()); - } else { - return IdLoader.fromLeafStoredFieldLoader(); - } + return IdLoader.create(indexService.mapperService()); } } From cd6dd731ce79fb76fc5c5aa0bd275f57c7d7eae0 Mon Sep 17 00:00:00 2001 From: tlrx Date: Thu, 6 Nov 2025 16:27:29 +0100 Subject: [PATCH 2/2] nit --- .../main/java/org/elasticsearch/index/mapper/IdLoader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/index/mapper/IdLoader.java b/server/src/main/java/org/elasticsearch/index/mapper/IdLoader.java index 6ed8628d051db..e309ce6454620 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/IdLoader.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/IdLoader.java @@ -59,9 +59,9 @@ static IdLoader create(MapperService mapperService) { } } } - return IdLoader.createTsIdLoader(indexRouting, routingPaths, indexSettings.useTimeSeriesSyntheticId()); + return createTsIdLoader(indexRouting, routingPaths, indexSettings.useTimeSeriesSyntheticId()); } else { - return IdLoader.fromLeafStoredFieldLoader(); + return fromLeafStoredFieldLoader(); } }