-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Allow metadata fields in the _source #61590
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
8a65d1c
d83b677
76f3dc3
4934129
a168a1b
2effa2f
1f5aa63
78faca3
1346865
39d19fe
f0bb957
a734ea8
b8b3a9d
1560e73
0c962c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,6 +45,14 @@ MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, | |
* @param parserContext context that may be useful to build the field like analyzers | ||
*/ | ||
MetadataFieldMapper getDefault(ParserContext parserContext); | ||
|
||
/** | ||
* @return Whether a metadata field can be included in the document _source. | ||
*/ | ||
default boolean isAllowedInSource() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering if we really need this new flag
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jtibshirani I agree with you that delegating this to
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't think we need to optimize performance in this case because it's an error condition (and should be a rare one too).
I agree that the logic is complex/ hard to read! I haven't deeply looked into the refactoring myself -- maybe you could try it out and we can rediscuss the approach if you see a roadblock ? |
||
// By default return false for metadata fields. | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* | ||
* 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.document.StringField; | ||
import org.elasticsearch.common.xcontent.XContentParser; | ||
import org.elasticsearch.plugins.MapperPlugin; | ||
import org.elasticsearch.plugins.Plugin; | ||
|
||
import java.io.IOException; | ||
import java.util.Collections; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* Mapper plugin providing a mock metadata field mapper implementation that supports setting its value | ||
* through the document source. | ||
*/ | ||
public class MockMetadataMapperPlugin extends Plugin implements MapperPlugin { | ||
|
||
/** | ||
* A mock metadata field mapper that supports being set from the document source. | ||
*/ | ||
public static class MockMetadataMapper extends MetadataFieldMapper { | ||
|
||
static final String CONTENT_TYPE = "_mock_metadata"; | ||
static final String FIELD_NAME = "_mock_metadata"; | ||
|
||
protected MockMetadataMapper() { | ||
super(new KeywordFieldMapper.KeywordFieldType(FIELD_NAME)); | ||
} | ||
|
||
@Override | ||
protected void parseCreateField(ParseContext context) throws IOException { | ||
if (context.parser().currentToken() == XContentParser.Token.VALUE_STRING) { | ||
context.doc().add(new StringField(FIELD_NAME, context.parser().text(), Field.Store.YES)); | ||
} else { | ||
jtibshirani marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return; | ||
} | ||
} | ||
|
||
@Override | ||
public Iterator<Mapper> iterator() { | ||
return Collections.emptyIterator(); | ||
} | ||
|
||
@Override | ||
protected String contentType() { | ||
return CONTENT_TYPE; | ||
} | ||
|
||
@Override | ||
public void preParse(ParseContext context) throws IOException { | ||
} | ||
|
||
@Override | ||
public void postParse(ParseContext context) throws IOException { | ||
} | ||
|
||
public static class Builder extends MetadataFieldMapper.Builder { | ||
|
||
protected Builder() { | ||
super(FIELD_NAME); | ||
} | ||
|
||
@Override | ||
protected List<Parameter<?>> getParameters() { | ||
return Collections.emptyList(); | ||
} | ||
|
||
@Override | ||
public MockMetadataMapper build(BuilderContext context) { | ||
return new MockMetadataMapper(); | ||
} | ||
} | ||
|
||
public static final TypeParser PARSER = new ConfigurableTypeParser( | ||
c -> new MockMetadataMapper(), | ||
c -> new MockMetadataMapper.Builder()) { | ||
|
||
@Override | ||
public boolean isAllowedInSource() { | ||
return true; | ||
} | ||
}; | ||
} | ||
|
||
@Override | ||
public Map<String, MetadataFieldMapper.TypeParser> getMetadataMappers() { | ||
return Collections.singletonMap(MockMetadataMapper.CONTENT_TYPE, MockMetadataMapper.PARSER); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reasoning for rejecting null and non-leaf values here?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jimczi and I had a discussion about the possible use cases we want to cover with this feature in the near future and agreed that for the sake of simplicity we should only accept non-null values (no objects or arrays).
I don't have any strong opinions and I am happy to revisit this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think null should be accepted but non-leaf values seemed more challenging. Now that I re-think about it, it shouldn't be an issue as long as we consume the value from the root (object or not).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So +1 to handle object, arrays and null values and let the metadata field mapper deals with it.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, let me work on this again