-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Remove types from internal GetFieldMappings request/response objects #48815
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
Remove types from internal GetFieldMappings request/response objects #48815
Conversation
Pinging @elastic/es-core-features (:Core/Features/Indices APIs) |
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 looks good to me, just some small suggestions.
@@ -53,7 +53,9 @@ public GetFieldMappingsRequest() {} | |||
public GetFieldMappingsRequest(StreamInput in) throws IOException { | |||
super(in); | |||
indices = in.readStringArray(); | |||
types = in.readStringArray(); | |||
if (in.getVersion().before(Version.V_8_0_0)) { | |||
in.readStringArray(); |
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 could throw an IllegalArgumentException here (as we discussed doing in other APIs).
for (int j = 0; j < typesSize; j++) { | ||
String type = in.readString(); | ||
Map<String, FieldMappingMetaData> fieldMapBuilder = new HashMap<>(); | ||
if (in.getVersion().before(Version.V_8_0_0)) { |
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.
Small comment, we could structure this as
if (in.getVersion().before(Version.V_8_0_0)) {
int typesSize = in.readVInt();
assert typesSize <= 1;
in.readString(); // type
}
This would allow for unifying the following code and also for keeping the map pre-sizing (new HashMap<>(fieldSize);
).
out.writeVInt(1); | ||
out.writeString(MapperService.SINGLE_MAPPING_NAME); | ||
out.writeVInt(indexEntry.getValue().size()); | ||
for (Map.Entry<String, FieldMappingMetaData> fieldEntry : indexEntry.getValue().entrySet()) { |
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.
Same small suggestion here, we could unify the part
out.writeVInt(indexEntry.getValue().size());
for (Map.Entry<String, FieldMappingMetaData> fieldEntry : indexEntry.getValue().entrySet()) {
...
}
Oops, I just saw some tests are failing related to field mappings. I'll do a quick re-review once those are addressed. |
GetFieldMappingsResponse response = client().admin().indices().prepareGetFieldMappings("index1").setFields("non-existent").get(); | ||
Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetaData>> mappings = response.mappings(); | ||
assertEquals(1, mappings.size()); | ||
Map<String, GetFieldMappingsResponse.FieldMappingMetaData> fieldmapping = mappings.get("index1"); |
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.
Small comment, fieldmapping
-> fieldMapping
.
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.
Sorry for the confusion -- I was over-eager on approving (again) and noticed an API change that is important to discuss.
@@ -16,4 +16,4 @@ | |||
index: test_index | |||
fields: not_existent | |||
|
|||
- match: { 'test_index.mappings': {}} |
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 just realized this doesn't seem right -- why did the response change here? It seems like an API break to start returning a completely empty response.
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 threw me as well, but if you look at the history it's actually restoring the behaviour that was there before include_type_name
was added - see #37210. There's specific logic in RestGetFieldMappingAction
to return an empty response if the index exists but the field doesn't, but it wasn't being tripped beforehand because no types
parameter was included in the request. Now that types
is gone entirely it has reverted back to the previous behaviour, but I agree it seems a bit odd - maybe we should just remove this extra logic entirely?
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 see now, thanks for the context! Looks like I subtly changed the behavior there without an explicit discussion.
I also think we should remove the extra logic. Given that we already used this new response format for a whole major release, I think it'd be confusing to change this format again in 8.0. It's also a breaking change that the user can't opt out of.
I noticed that with the current behavior we only return an empty object when a single field is provided. If the request contains two fields that are both non-existent, then we still return the format { "index": { "mappings": {} }
. This is true both of the current PR and the old 6.x logic. This seems quite inconsistent, and suggests to me that it's not so bad to keep the { "index": { "mappings": {} }
format everywhere.
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'll remove that special case and re-test
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.
Sorry for the slow turn-around on the review and that there has been a lot of back-and-forth on the PR.
I took a look at your latest changes, especially the fixes around null field mappings in 7e8a493. It seemed to me like the cleanest approach would be to remove all references to probablySingleFieldRequest
, since it is no longer has a use. I think this would also let us remove FieldMappingMetaData.NULL
.
However I am unsure about removing these because I can't determine why they were originally introduced in #4822. I've read over the PR and issue but still don't understand their purpose. Do you have an understanding of why there was special logic around probablySingleFieldRequest
? I think this would be good to investigate (now or in a follow-up) to make sure that we didn't regress something in the response format through our types removal efforts.
I think this is to do with how the maps were built prior to this refactoring, in that because of the double-nested maps it wasn't obvious when a field was missing vs when a type was missing. Now that we only have two levels it's easy to handle a present index but missing field just by passing around empty maps. I've removed the |
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.
Looks good to me, thanks for your patience on this one :) I'll follow-up with the original author on why the logic around probablySingleFieldRequest
was added and will loop back if I find anything that needs addressing.
@@ -45,12 +44,13 @@ | |||
} | |||
fields = in.readStringArray(); | |||
includeDefaults = in.readBoolean(); | |||
probablySingleFieldRequest = in.readBoolean(); | |||
if (in.getVersion().before(Version.V_8_0_0)) { |
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.
Small comment, we could add a comment here explaining this backwards-compatibility logic.
Type filters and intermediate type levels in mappings responses have already been
removed from the GetFieldMappings REST layer; we can also remove them from the
internal Node client classes.
Relates to #41059