Elasticsearch 查询将多个值匹配到单个字段
Elasticsearch query match multiple values to single field
正在尝试获取与字段 ABC
的值 X1
或 Y1
匹配的文档。尝试了 must
或 should
查询,但未获得预期结果。有人可以建议我应该尝试什么样的查询吗?使用 HighLevelRestClient
.
{
"bool" : {
"must" : [
{
"term" : {
"ABC" : {
"value" : "X1",
"boost" : 1.0
}
}
},
{
"term" : {
"ABC" : {
"value" : "Y1",
"boost" : 1.0
}
}
}
]
}
}
或
{
"bool" : {
"should" : [
{
"term" : {
"ABC" : {
"value" : "X1",
"boost" : 1.0
}
}
},
{
"term" : {
"ABC" : {
"value" : "Y1",
"boost" : 1.0
}
}
}
]
}
}
映射
{
"mappings": {
"properties": {
"ABC": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 2
}
}
},
mustNot
条件正常。如果我只是反转条件并忽略字段值,那么我会得到结果。
X1 和 Y1 是精确的字段值(考虑枚举)
BoolQueryBuilder x = QueryBuilders.boolQuery();
for (SomeEnum enum : enums) {
x.should(QueryBuilders.termQuery("ABC",enum.name());
}
仍然查询returns所有文档。这应该已经将文档过滤为匹配值
示例文档
{
"_index": "some_index",
"_type": "_doc",
"_id": "uyeuyeuryweoyqweo",
"_score": 1.0,
"_source": {
"A": true
"ABC": "X1"
"WS": "E"
}
},
{
"_index" : "some_index",
"_type" : "_doc",
"_id" : "uyeuyeuryweoyqweo1",
"_score" : 1.0,
"_source" : {
"A" : true,
"ABC" : "Y1",
"WS" : "MMM"
}
}
由于您没有提供映射,可能的原因是搜索时间标记与 index-tokens 不匹配。
由于您正在使用 term
查询,因此未按 doc
中所述进行分析
Returns documents that contain an exact term in a provided field.
这意味着您在索引中的文档必须包含与 X1
和 Y1
完全相同的标记,并且如果这些字段是 text
字段并且您没有定义任何比 elasticsearch 使用的分析器standard
分析器,其中 lowercases
标记,因此在索引 x1
和 y1
中将被存储,没有任何匹配。
EDIT :正如所怀疑的那样,问题是由于 term
在 text
字段上使用的查询,下面的查询将给出预期的结果
{
"bool" : {
"should" : [
{
"term" : {
"ABC.keyword" : {
"value" : "X1",
"boost" : 1.0
}
}
},
{
"term" : {
"ABC.keyword" : {
"value" : "Y1",
"boost" : 1.0
}
}
}
]
}
}
正在尝试获取与字段 ABC
的值 X1
或 Y1
匹配的文档。尝试了 must
或 should
查询,但未获得预期结果。有人可以建议我应该尝试什么样的查询吗?使用 HighLevelRestClient
.
{
"bool" : {
"must" : [
{
"term" : {
"ABC" : {
"value" : "X1",
"boost" : 1.0
}
}
},
{
"term" : {
"ABC" : {
"value" : "Y1",
"boost" : 1.0
}
}
}
]
}
}
或
{
"bool" : {
"should" : [
{
"term" : {
"ABC" : {
"value" : "X1",
"boost" : 1.0
}
}
},
{
"term" : {
"ABC" : {
"value" : "Y1",
"boost" : 1.0
}
}
}
]
}
}
映射
{
"mappings": {
"properties": {
"ABC": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 2
}
}
},
mustNot
条件正常。如果我只是反转条件并忽略字段值,那么我会得到结果。
X1 和 Y1 是精确的字段值(考虑枚举)
BoolQueryBuilder x = QueryBuilders.boolQuery();
for (SomeEnum enum : enums) {
x.should(QueryBuilders.termQuery("ABC",enum.name());
}
仍然查询returns所有文档。这应该已经将文档过滤为匹配值
示例文档
{
"_index": "some_index",
"_type": "_doc",
"_id": "uyeuyeuryweoyqweo",
"_score": 1.0,
"_source": {
"A": true
"ABC": "X1"
"WS": "E"
}
},
{
"_index" : "some_index",
"_type" : "_doc",
"_id" : "uyeuyeuryweoyqweo1",
"_score" : 1.0,
"_source" : {
"A" : true,
"ABC" : "Y1",
"WS" : "MMM"
}
}
由于您没有提供映射,可能的原因是搜索时间标记与 index-tokens 不匹配。
由于您正在使用 term
查询,因此未按 doc
Returns documents that contain an exact term in a provided field.
这意味着您在索引中的文档必须包含与 X1
和 Y1
完全相同的标记,并且如果这些字段是 text
字段并且您没有定义任何比 elasticsearch 使用的分析器standard
分析器,其中 lowercases
标记,因此在索引 x1
和 y1
中将被存储,没有任何匹配。
EDIT :正如所怀疑的那样,问题是由于 term
在 text
字段上使用的查询,下面的查询将给出预期的结果
{
"bool" : {
"should" : [
{
"term" : {
"ABC.keyword" : {
"value" : "X1",
"boost" : 1.0
}
}
},
{
"term" : {
"ABC.keyword" : {
"value" : "Y1",
"boost" : 1.0
}
}
}
]
}
}