-
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
Merged
romseygeek
merged 15 commits into
elastic:master
from
romseygeek:types-removal/getfieldmappings
Nov 27, 2019
Merged
Changes from 3 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
59ddbd5
Remove types from internal GetFieldMappings request/response objects
romseygeek f660bf3
feedback; tests
romseygeek c7ce92a
Merge remote-tracking branch 'origin/master' into types-removal/getfi…
romseygeek 0e910dc
Merge remote-tracking branch 'origin/master' into types-removal/getfi…
romseygeek cc2af67
Remove special-case when no fields are found
romseygeek 7e8a493
better tests for null mappings
romseygeek 86c90ad
Merge remote-tracking branch 'origin/master' into types-removal/getfi…
romseygeek 5791352
cleanup
romseygeek 6b06af6
Merge remote-tracking branch 'origin/master' into types-removal/getfi…
romseygeek e25bc12
Merge remote-tracking branch 'origin/master' into types-removal/getfi…
romseygeek c6ece6c
Merge remote-tracking branch 'origin/master' into types-removal/getfi…
romseygeek 6a3847e
Remove special-case logic for existing index but non-existing field
romseygeek 50bb694
plugin compilation
romseygeek 0f137dd
watcher test
romseygeek 2f96021
Merge remote-tracking branch 'origin/master' into types-removal/getfi…
romseygeek File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 |
---|---|---|
|
@@ -19,6 +19,7 @@ | |
|
||
package org.elasticsearch.action.admin.indices.mapping.get; | ||
|
||
import org.elasticsearch.Version; | ||
import org.elasticsearch.action.ActionResponse; | ||
import org.elasticsearch.common.ParseField; | ||
import org.elasticsearch.common.bytes.BytesArray; | ||
|
@@ -34,6 +35,7 @@ | |
import org.elasticsearch.common.xcontent.XContentParser; | ||
import org.elasticsearch.common.xcontent.XContentType; | ||
import org.elasticsearch.index.mapper.Mapper; | ||
import org.elasticsearch.index.mapper.MapperService; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
|
@@ -55,64 +57,35 @@ public class GetFieldMappingsResponse extends ActionResponse implements ToXConte | |
|
||
private static final ParseField MAPPINGS = new ParseField("mappings"); | ||
|
||
private static final ObjectParser<Map<String, Map<String, FieldMappingMetaData>>, String> PARSER = | ||
new ObjectParser<>(MAPPINGS.getPreferredName(), true, HashMap::new); | ||
|
||
static { | ||
PARSER.declareField((p, typeMappings, index) -> { | ||
p.nextToken(); | ||
while (p.currentToken() == XContentParser.Token.FIELD_NAME) { | ||
final String typeName = p.currentName(); | ||
|
||
if (p.nextToken() == XContentParser.Token.START_OBJECT) { | ||
final Map<String, FieldMappingMetaData> typeMapping = new HashMap<>(); | ||
typeMappings.put(typeName, typeMapping); | ||
|
||
while (p.nextToken() == XContentParser.Token.FIELD_NAME) { | ||
final String fieldName = p.currentName(); | ||
final FieldMappingMetaData fieldMappingMetaData = FieldMappingMetaData.fromXContent(p); | ||
typeMapping.put(fieldName, fieldMappingMetaData); | ||
} | ||
} else { | ||
p.skipChildren(); | ||
} | ||
p.nextToken(); | ||
} | ||
}, MAPPINGS, ObjectParser.ValueType.OBJECT); | ||
} | ||
private final Map<String, Map<String, FieldMappingMetaData>> mappings; | ||
|
||
// TODO remove the middle `type` level of this | ||
private final Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings; | ||
|
||
GetFieldMappingsResponse(Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings) { | ||
GetFieldMappingsResponse(Map<String, Map<String, FieldMappingMetaData>> mappings) { | ||
this.mappings = mappings; | ||
} | ||
|
||
GetFieldMappingsResponse(StreamInput in) throws IOException { | ||
super(in); | ||
int size = in.readVInt(); | ||
Map<String, Map<String, Map<String, FieldMappingMetaData>>> indexMapBuilder = new HashMap<>(size); | ||
Map<String, Map<String, FieldMappingMetaData>> indexMapBuilder = new HashMap<>(size); | ||
for (int i = 0; i < size; i++) { | ||
String index = in.readString(); | ||
int typesSize = in.readVInt(); | ||
Map<String, Map<String, FieldMappingMetaData>> typeMapBuilder = new HashMap<>(typesSize); | ||
for (int j = 0; j < typesSize; j++) { | ||
String type = in.readString(); | ||
int fieldSize = in.readVInt(); | ||
Map<String, FieldMappingMetaData> fieldMapBuilder = new HashMap<>(fieldSize); | ||
for (int k = 0; k < fieldSize; k++) { | ||
fieldMapBuilder.put(in.readString(), new FieldMappingMetaData(in.readString(), in.readBytesReference())); | ||
} | ||
typeMapBuilder.put(type, unmodifiableMap(fieldMapBuilder)); | ||
if (in.getVersion().before(Version.V_8_0_0)) { | ||
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. Small comment, we could structure this as
This would allow for unifying the following code and also for keeping the map pre-sizing ( |
||
int typesSize = in.readVInt(); | ||
assert typesSize == 1; | ||
in.readString(); // type | ||
} | ||
int fieldSize = in.readVInt(); | ||
Map<String, FieldMappingMetaData> fieldMapBuilder = new HashMap<>(fieldSize); | ||
for (int k = 0; k < fieldSize; k++) { | ||
fieldMapBuilder.put(in.readString(), new FieldMappingMetaData(in.readString(), in.readBytesReference())); | ||
} | ||
indexMapBuilder.put(index, unmodifiableMap(typeMapBuilder)); | ||
indexMapBuilder.put(index, unmodifiableMap(fieldMapBuilder)); | ||
} | ||
mappings = unmodifiableMap(indexMapBuilder); | ||
|
||
} | ||
|
||
/** returns the retrieved field mapping. The return map keys are index, type, field (as specified in the request). */ | ||
public Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings() { | ||
/** returns the retrieved field mapping. The return map keys are index, field (as specified in the request). */ | ||
public Map<String, Map<String, FieldMappingMetaData>> mappings() { | ||
return mappings; | ||
} | ||
|
||
|
@@ -122,32 +95,23 @@ public Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings() { | |
* @param field field name as specified in the {@link GetFieldMappingsRequest} | ||
* @return FieldMappingMetaData for the requested field or null if not found. | ||
*/ | ||
public FieldMappingMetaData fieldMappings(String index, String type, String field) { | ||
Map<String, Map<String, FieldMappingMetaData>> indexMapping = mappings.get(index); | ||
public FieldMappingMetaData fieldMappings(String index, String field) { | ||
Map<String, FieldMappingMetaData> indexMapping = mappings.get(index); | ||
if (indexMapping == null) { | ||
return null; | ||
} | ||
Map<String, FieldMappingMetaData> typeMapping = indexMapping.get(type); | ||
if (typeMapping == null) { | ||
return null; | ||
} | ||
return typeMapping.get(field); | ||
return indexMapping.get(field); | ||
} | ||
|
||
@Override | ||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
builder.startObject(); | ||
for (Map.Entry<String, Map<String, Map<String, FieldMappingMetaData>>> indexEntry : mappings.entrySet()) { | ||
for (Map.Entry<String, Map<String, FieldMappingMetaData>> indexEntry : mappings.entrySet()) { | ||
builder.startObject(indexEntry.getKey()); | ||
builder.startObject(MAPPINGS.getPreferredName()); | ||
|
||
Map<String, FieldMappingMetaData> mappings = null; | ||
for (Map.Entry<String, Map<String, FieldMappingMetaData>> typeEntry : indexEntry.getValue().entrySet()) { | ||
assert mappings == null; | ||
mappings = typeEntry.getValue(); | ||
} | ||
if (mappings != null) { | ||
addFieldMappingsToBuilder(builder, params, mappings); | ||
if (indexEntry.getValue() != null) { | ||
addFieldMappingsToBuilder(builder, params, indexEntry.getValue()); | ||
} | ||
|
||
builder.endObject(); | ||
|
@@ -255,18 +219,18 @@ public int hashCode() { | |
@Override | ||
public void writeTo(StreamOutput out) throws IOException { | ||
out.writeVInt(mappings.size()); | ||
for (Map.Entry<String, Map<String, Map<String, FieldMappingMetaData>>> indexEntry : mappings.entrySet()) { | ||
for (Map.Entry<String, Map<String, FieldMappingMetaData>> indexEntry : mappings.entrySet()) { | ||
out.writeString(indexEntry.getKey()); | ||
if (out.getVersion().before(Version.V_8_0_0)) { | ||
out.writeVInt(1); | ||
out.writeString(MapperService.SINGLE_MAPPING_NAME); | ||
} | ||
out.writeVInt(indexEntry.getValue().size()); | ||
for (Map.Entry<String, Map<String, FieldMappingMetaData>> typeEntry : indexEntry.getValue().entrySet()) { | ||
out.writeString(typeEntry.getKey()); | ||
out.writeVInt(typeEntry.getValue().size()); | ||
for (Map.Entry<String, FieldMappingMetaData> fieldEntry : typeEntry.getValue().entrySet()) { | ||
out.writeString(fieldEntry.getKey()); | ||
FieldMappingMetaData fieldMapping = fieldEntry.getValue(); | ||
out.writeString(fieldMapping.fullName()); | ||
out.writeBytesReference(fieldMapping.source); | ||
} | ||
for (Map.Entry<String, FieldMappingMetaData> fieldEntry : indexEntry.getValue().entrySet()) { | ||
out.writeString(fieldEntry.getKey()); | ||
FieldMappingMetaData fieldMapping = fieldEntry.getValue(); | ||
out.writeString(fieldMapping.fullName()); | ||
out.writeBytesReference(fieldMapping.source); | ||
} | ||
} | ||
} | ||
|
This file contains hidden or 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 hidden or 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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 inRestGetFieldMappingAction
to return an empty response if the index exists but the field doesn't, but it wasn't being tripped beforehand because notypes
parameter was included in the request. Now thattypes
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