-
Notifications
You must be signed in to change notification settings - Fork 24.6k
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
QL: constant_keyword support #53241
QL: constant_keyword support #53241
Changes from all commits
7540f06
2f92a65
23a1a7d
c5376c9
abad76c
1740adb
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 |
---|---|---|
|
@@ -25,6 +25,7 @@ | |
import org.elasticsearch.index.IndexNotFoundException; | ||
import org.elasticsearch.index.IndexSettings; | ||
import org.elasticsearch.xpack.ql.QlIllegalArgumentException; | ||
import org.elasticsearch.xpack.ql.type.ConstantKeywordEsField; | ||
import org.elasticsearch.xpack.ql.type.DataType; | ||
import org.elasticsearch.xpack.ql.type.DataTypeRegistry; | ||
import org.elasticsearch.xpack.ql.type.DateEsField; | ||
|
@@ -60,6 +61,7 @@ | |
import static java.util.Collections.emptyMap; | ||
import static java.util.Collections.emptySet; | ||
import static org.elasticsearch.action.ActionListener.wrap; | ||
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD; | ||
import static org.elasticsearch.xpack.ql.type.DataTypes.DATETIME; | ||
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD; | ||
import static org.elasticsearch.xpack.ql.type.DataTypes.OBJECT; | ||
|
@@ -298,8 +300,13 @@ public static IndexResolution mergedMappings(DataTypeRegistry typeRegistry, Stri | |
StringBuilder errorMessage = new StringBuilder(); | ||
|
||
boolean hasUnmapped = types.containsKey(UNMAPPED); | ||
// a keyword field and a constant_keyword field with the same name in two different indices are considered "compatible" | ||
// since a common use case of constant_keyword field involves two indices with a field having the same name: one being | ||
// a keyword, the other being a constant_keyword | ||
boolean hasCompatibleKeywords = types.containsKey(KEYWORD.esType()) && types.containsKey(CONSTANT_KEYWORD.esType()); | ||
int allowedTypesCount = (hasUnmapped ? 2 : 1) + (hasCompatibleKeywords ? 1 : 0); | ||
|
||
if (types.size() > (hasUnmapped ? 2 : 1)) { | ||
if (types.size() > allowedTypesCount) { | ||
// build the error message | ||
// and create a MultiTypeField | ||
|
||
|
@@ -344,6 +351,11 @@ public static IndexResolution mergedMappings(DataTypeRegistry typeRegistry, Stri | |
} | ||
} | ||
|
||
// if there are both a keyword and a constant_keyword type for this field, only keep the keyword as a common compatible type | ||
if (hasCompatibleKeywords) { | ||
types.remove(CONSTANT_KEYWORD.esType()); | ||
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. Removing the type all together might remove useful information. 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. This scenario is the one where two indices have the same named field with both The controversy for what to do in this specific case came from the scenario described here and is specifically tested here. |
||
} | ||
|
||
// everything checks | ||
return null; | ||
}); | ||
|
@@ -435,6 +447,9 @@ private static EsField createField(DataTypeRegistry typeRegistry, String fieldNa | |
if (esType == DATETIME) { | ||
return new DateEsField(fieldName, props, isAggregateable); | ||
} | ||
if (esType == CONSTANT_KEYWORD) { | ||
return new ConstantKeywordEsField(fieldName); | ||
} | ||
if (esType == UNSUPPORTED) { | ||
return new UnsupportedEsField(fieldName, typeName, null, props); | ||
} | ||
|
@@ -501,14 +516,14 @@ private static List<EsIndex> buildIndices(DataTypeRegistry typeRegistry, String[ | |
|
||
for (Entry<String, Map<String, FieldCapabilities>> entry : sortedFields) { | ||
String fieldName = entry.getKey(); | ||
Map<String, FieldCapabilities> types = entry.getValue(); | ||
|
||
// ignore size added by the mapper plugin | ||
if (FIELD_NAMES_BLACKLIST.contains(fieldName)) { | ||
continue; | ||
} | ||
|
||
// apply verification | ||
Map<String, FieldCapabilities> types = new LinkedHashMap<>(entry.getValue()); | ||
// apply verification and possibly remove the "duplicate" CONSTANT_KEYWORD field type | ||
final InvalidMappedField invalidField = validityVerifier.apply(fieldName, types); | ||
|
||
// filter meta fields and unmapped | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
package org.elasticsearch.xpack.ql.type; | ||
|
||
import java.util.Collections; | ||
|
||
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD; | ||
|
||
/** | ||
* SQL-related information about an index field with a constant_keyword type | ||
*/ | ||
public class ConstantKeywordEsField extends KeywordEsField { | ||
|
||
public ConstantKeywordEsField(String name) { | ||
super(name, CONSTANT_KEYWORD, Collections.emptyMap(), true, Short.MAX_VALUE, false, false); | ||
} | ||
|
||
} |
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.
Could you explain please, I don't get it.
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 cannot extract the value of a constant_keyword from _source because if there is no source for the field, Elasticsearch will still consider the field as having the constant value.
Take a look at the example in our docs. No value at indexing time means
level
isdebug
. So, for the second document in the sample, there is no _source forlevel
, but the value is stilldebug
in case there is a query filtering on that field.