-
Notifications
You must be signed in to change notification settings - Fork 24.9k
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
Add 'flatten' parameter to object mappers #78997
Conversation
Pinging @elastic/es-search (Team:Search) |
I want to let CI chew on this and I'm pretty sure there are further cleanups I can make in DocumentParser (which now has a bunch of unused code) and related tests, but it would be good to get some feedback on whether we think this is the right way of implementing this, at least as an external API. Note that as of now I have explicitly not implemented this on nested mappers, but it would be easy enough to extend it there. |
return mappingLookup.getMapping().mappingUpdate(root); | ||
} | ||
|
||
private static RootObjectMapper createDynamicUpdate(MappingLookup mappingLookup, |
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.
The vast bulk of this logic is now moved into the new ObjectMapper.Builder#addDynamic()
method. Instead of creating concrete object mappers and recursively merging them, instead we pass each mapper to a root object builder. The builder checks to see if there are any dots in the mapper's field name, and if there are and the object is not flattened then we strip off the first object name, create the relevant object builder if it doesn't already exist, and pass the shortened name along with the mapper down to the next level. If the object is flattened, then we just add the mapper directly underneath it.
Tuple<Integer, ObjectMapper> parentMapperTuple = getDynamicParentMapper(context, paths, parentMapper); | ||
parentMapper = parentMapperTuple.v2(); | ||
int pathLength = parentMapperTuple.v1(); | ||
StringBuilder compositeFieldName = new StringBuilder(paths[pathLength]); |
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.
This part allows us to handle deeply nested object paths that become flattened at some arbitrary point. getDynamicParentMapper
will stop building intermediate object mappers if one of them is flattened, and this logic builds up the final field name from the point of the flattened object.
@Override | ||
public String toString() { | ||
return name() + ":" + Strings.toString(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.
Not strictly related, but it made debugging this so much easier that I thought it worth leaving in.
copy.numericDetection = new Explicit<>(Defaults.NUMERIC_DETECTION, false); | ||
//also no need to carry the already defined runtime fields, only new ones need to be added | ||
copy.runtimeFields.clear(); | ||
return copy; |
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.
We don't need to set all the dynamicTemplates, etc, because we're creating a Builder which already has all these set to implicit defaults.
Hi @romseygeek, I've created a changelog YAML for you. |
Objects with
flatten:true
will automatically flatten all sub-objects into dot-delimitedfields, allowing users to specify field names that are dot-prefixes of other fields.
For example, say you have a set of fields
metric.value
,metric.value.min
andmetric.value.max
. Settingflatten:true
on the top-levelmetric
object willallow
value
,value.min
andvalue.max
to all appear as leaf fields:Objects with
flatten:true
cannot contain further object mappers.Relates to #63530