-
Notifications
You must be signed in to change notification settings - Fork 24.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add NestedPathFieldMapper to store nested path information (#51100)
Currently nested documents repurpose the _type field to store their nested paths. This commit adds a dedicated _nested_path field instead, which decouples this information from types and will allow the removal of the _type field entirely further down the line. To preserve backwards compatibility, references to this field are mediated via methods that take an index settings object, and indexes created before 8x still use the _type field. Relates to #41059 Closes #24362
- Loading branch information
1 parent
551a83a
commit 1dc9dd4
Showing
23 changed files
with
375 additions
and
133 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
164 changes: 164 additions & 0 deletions
164
server/src/main/java/org/elasticsearch/index/mapper/NestedPathFieldMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
/* | ||
* Licensed to Elasticsearch under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
package org.elasticsearch.index.mapper; | ||
|
||
import org.apache.lucene.document.Field; | ||
import org.apache.lucene.index.IndexOptions; | ||
import org.apache.lucene.index.IndexableField; | ||
import org.apache.lucene.index.Term; | ||
import org.apache.lucene.search.Query; | ||
import org.apache.lucene.search.TermQuery; | ||
import org.apache.lucene.util.BytesRef; | ||
import org.elasticsearch.Version; | ||
import org.elasticsearch.common.lucene.Lucene; | ||
import org.elasticsearch.common.settings.Settings; | ||
import org.elasticsearch.common.xcontent.XContentBuilder; | ||
import org.elasticsearch.index.IndexSettings; | ||
import org.elasticsearch.index.query.QueryShardContext; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class NestedPathFieldMapper extends MetadataFieldMapper { | ||
|
||
public static final String NAME_PRE_V8 = "_type"; | ||
public static final String NAME = "_nested_path"; | ||
|
||
public static String name(Settings settings) { | ||
if (Version.indexCreated(settings).before(Version.V_8_0_0)) { | ||
return NAME_PRE_V8; | ||
} | ||
return NAME; | ||
} | ||
|
||
public static Query filter(Settings settings, String path) { | ||
return new TermQuery(new Term(name(settings), new BytesRef(path))); | ||
} | ||
|
||
public static Field field(Settings settings, String path) { | ||
return new Field(name(settings), path, Defaults.FIELD_TYPE); | ||
} | ||
|
||
public static class Defaults { | ||
|
||
public static final MappedFieldType FIELD_TYPE = new NestedPathFieldType(); | ||
|
||
static { | ||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS); | ||
FIELD_TYPE.setTokenized(false); | ||
FIELD_TYPE.setStored(false); | ||
FIELD_TYPE.setOmitNorms(true); | ||
FIELD_TYPE.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); | ||
FIELD_TYPE.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); | ||
FIELD_TYPE.freeze(); | ||
} | ||
} | ||
|
||
public static class TypeParser implements MetadataFieldMapper.TypeParser { | ||
@Override | ||
public MetadataFieldMapper.Builder<?,?> parse(String name, Map<String, Object> node, | ||
ParserContext parserContext) throws MapperParsingException { | ||
throw new MapperParsingException(name(parserContext.mapperService().getIndexSettings().getSettings()) + " is not configurable"); | ||
} | ||
|
||
@Override | ||
public MetadataFieldMapper getDefault(ParserContext context) { | ||
final IndexSettings indexSettings = context.mapperService().getIndexSettings(); | ||
return new NestedPathFieldMapper(indexSettings, defaultFieldType(indexSettings)); | ||
} | ||
} | ||
|
||
public static final class NestedPathFieldType extends StringFieldType { | ||
|
||
NestedPathFieldType() { | ||
} | ||
|
||
protected NestedPathFieldType(NestedPathFieldType ref) { | ||
super(ref); | ||
} | ||
|
||
@Override | ||
public MappedFieldType clone() { | ||
return new NestedPathFieldType(this); | ||
} | ||
|
||
@Override | ||
public String typeName() { | ||
return NAME; | ||
} | ||
|
||
@Override | ||
public boolean isSearchable() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public Query existsQuery(QueryShardContext context) { | ||
throw new UnsupportedOperationException("Cannot run exists() query against the nested field path"); | ||
} | ||
} | ||
|
||
private NestedPathFieldMapper(IndexSettings indexSettings, MappedFieldType existing) { | ||
this(existing == null ? defaultFieldType(indexSettings) : existing.clone(), | ||
indexSettings); | ||
} | ||
|
||
private NestedPathFieldMapper(MappedFieldType fieldType, IndexSettings indexSettings) { | ||
super(name(indexSettings.getSettings()), fieldType, defaultFieldType(indexSettings), indexSettings.getSettings()); | ||
} | ||
|
||
private static MappedFieldType defaultFieldType(IndexSettings indexSettings) { | ||
MappedFieldType defaultFieldType = Defaults.FIELD_TYPE.clone(); | ||
defaultFieldType.setIndexOptions(IndexOptions.NONE); | ||
defaultFieldType.setHasDocValues(false); | ||
defaultFieldType.setName(name(indexSettings.getSettings())); | ||
return defaultFieldType; | ||
} | ||
|
||
@Override | ||
public void preParse(ParseContext context) throws IOException { | ||
super.parse(context); | ||
} | ||
|
||
@Override | ||
public void parse(ParseContext context) throws IOException { | ||
// we parse in pre parse | ||
} | ||
|
||
@Override | ||
protected void parseCreateField(ParseContext context, List<IndexableField> fields) throws IOException { | ||
} | ||
|
||
@Override | ||
protected String contentType() { | ||
return NAME; | ||
} | ||
|
||
@Override | ||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
return builder; | ||
} | ||
|
||
@Override | ||
protected void doMerge(Mapper mergeWith) { | ||
// do nothing here, no merging, but also no exception | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.