所以我有一个ES文档,我无法控制其结构,因此我不能更改映射。我有一个location
字段(映射类型text
),它是"分析"的。ES。我的文档是这样的:
[
{
title: "Something that happened in the UK",
location: "United States, London"
},
{
title: "Something that happened in the US",
location: "United Kingdom, London"
}
]
我正试图编写一个查询,只过滤location
字段,并返回united states
或united kingdom
的结果,但不是两者。
{
"query":
{
"match": {
"location": { "query": "united statess" }
}
}
这不起作用,因为单词united
出现在两个位置名称中。不幸的是,该字段被分析,它将返回两个结果。我试过将"operator" : "and"
添加到"匹配"中。查询,但不返回任何结果。我错过了什么?有没有办法通过"匹配"来实现这一点?查询?
我知道您正在尝试在位置字段上创建xor过滤器。在Elasticsearch的布尔查询中没有xor快捷键,但是xor可以用OR、AND和NOT操作符构造。
必须→
must_not ->不是
所以有两种方法可以用这些操作符(伪代码)构造异或过滤器:
must( (should(uk, us), must_not( must(uk, us))
should( must( uk, must_not(us)), must(must_not(uk), us))
还有更可读的Query_String查询,它支持布尔语法。
下面是一个bool和match查询组合的例子,以及一个字符串查询的例子,它们都充当排他或,你可以在Kibana开发工具中测试这些查询:
PUT /test_xor
PUT /test_xor/_doc/1
{
"type": "neither uk nor us",
"location": [
{
"title": "Something that happened in germany",
"location": "Germany, Berlin"
},
{
"title": "Something that happened in the France",
"location": "France, Paris"
}
]
}
PUT /test_xor/_doc/2
{
"type": "only us",
"location": [
{
"title": "Something that happened in germany",
"location": "Germany, Berlin"
},
{
"title": "Something that happened in the US",
"location": "United States, London"
}
]
}
PUT /test_xor/_doc/3
{
"type": "only uk",
"location": [
{
"title": "Something that happened in germany",
"location": "Germany, Berlin"
},
{
"title": "Something that happened in the US",
"location": "United States, London"
}
]
}
PUT /test_xor/_doc/4
{
"type": "uk and us",
"location": [
{
"title": "Something that happened in the US",
"location": "United States, London"
},
{
"title": "Something that happened in the UK",
"location": "United Kingdom, London"
}
]
}
GET /test_xor/_search
{
"query": {
"query_string" : {
"query": "("United States, London" OR "United Kingdom, London") AND NOT ("United States, London" AND "United Kingdom, London")",
"fields": ["location.location"]
}
}
}
GET /test_xor/_search
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"match": {
"location.location": {
"query": "United States, London",
"operator": "and"
}
}
},
{
"match": {
"location.location": {
"query": " OR "United Kingdom, London"",
"operator": "and"
}
}
}
]
}
},
{
"bool": {
"must_not": [
{
"bool": {
"must": [
{
"match": {
"location.location": {
"query": "United States, London",
"operator": "and"
}
}
},
{
"match": {
"location.location": {
"query": "United Kingdom, London",
"operator": "and"
}
}
}
]
}
}
]
}
}
]
}
}
}
在尝试了各种事情之后,我想出了这个解决方案,似乎是有效的。尽管出于某种原因,我觉得有更好的方法来实现这一点:
回答我自己的问题,这有意义吗?🤔
{
"query": {
"bool": {
"must": [
{
"match": {
"location": "united"
}
},
{
"match": {
"location": "states"
}
}
]
}
}
}
[EDIT]:我实际上已经找到了一个更好的解决方案,看起来像这样:
{
"query": {
{
"match_phrase": {
"location": "united states"
}
}
}