Skip to content

Commit 412f12e

Browse files
committed
Enable nested fields in time-series mode indices
1 parent 59b2d57 commit 412f12e

File tree

3 files changed

+16
-5
lines changed

3 files changed

+16
-5
lines changed

server/src/main/java/org/elasticsearch/index/IndexMode.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import org.elasticsearch.index.mapper.MapperService;
3030
import org.elasticsearch.index.mapper.MappingLookup;
3131
import org.elasticsearch.index.mapper.MetadataFieldMapper;
32-
import org.elasticsearch.index.mapper.NestedLookup;
3332
import org.elasticsearch.index.mapper.ProvidedIdFieldMapper;
3433
import org.elasticsearch.index.mapper.RoutingFieldMapper;
3534
import org.elasticsearch.index.mapper.RoutingFields;
@@ -156,9 +155,6 @@ private static String error(Setting<?> unsupported) {
156155

157156
@Override
158157
public void validateMapping(MappingLookup lookup) {
159-
if (lookup.nestedLookup() != NestedLookup.EMPTY) {
160-
throw new IllegalArgumentException("cannot have nested fields when index is in " + tsdbMode());
161-
}
162158
if (((RoutingFieldMapper) lookup.getMapper(RoutingFieldMapper.NAME)).required()) {
163159
throw new IllegalArgumentException(routingRequiredBad());
164160
}

server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,8 +665,13 @@ public final DocumentParserContext createNestedContext(NestedObjectMapper nested
665665
if (idField != null) {
666666
// We just need to store the id as indexed field, so that IndexWriter#deleteDocuments(term) can then
667667
// delete it when the root document is deleted too.
668-
// NOTE: we don't support nested fields in tsdb so it's safe to assume the standard id mapper.
669668
doc.add(new StringField(IdFieldMapper.NAME, idField.binaryValue(), Field.Store.NO));
669+
} else if (indexSettings().getMode() == IndexMode.TIME_SERIES) {
670+
// For time series indices, the _id is generated from the _tsid, which in turn is generated from the values of the configured
671+
// routing fields. At this point in document parsing, we can't guarantee that we've parsed all the routing fields yet, so the
672+
// parent document's _id is not yet available.
673+
// So we just add the child document without the parent _id, then in TimeSeriesIdFieldMapper#postParse we set the _id on all
674+
// child documents once we've calculated it.
670675
} else {
671676
throw new IllegalStateException("The root document of a nested document should have an _id field");
672677
}

server/src/main/java/org/elasticsearch/index/mapper/TimeSeriesIdFieldMapper.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99

1010
package org.elasticsearch.index.mapper;
1111

12+
import org.apache.lucene.document.Field;
1213
import org.apache.lucene.document.SortedDocValuesField;
14+
import org.apache.lucene.document.StringField;
1315
import org.apache.lucene.search.Query;
1416
import org.apache.lucene.util.BytesRef;
1517
import org.elasticsearch.common.Strings;
@@ -142,6 +144,14 @@ public void postParse(DocumentParserContext context) throws IOException {
142144
: null,
143145
timeSeriesId
144146
);
147+
148+
// We need to add the uid or id to nested Lucene documents so that when a document gets deleted, the nested documents are
149+
// also deleted. Usually this happens when the nested document is created (in DocumentParser#createNestedContext), but
150+
// for time-series indices the _id isn't available at that point.
151+
assert context.id() != null;
152+
for (LuceneDocument doc : context.nonRootDocuments()) {
153+
doc.add(new StringField(IdFieldMapper.NAME, Uid.encodeId(context.id()), Field.Store.NO));
154+
}
145155
}
146156

147157
private IndexVersion getIndexVersionCreated(final DocumentParserContext context) {

0 commit comments

Comments
 (0)