简而言之:当一个字段具有多个值时,如何仅将两个过滤器都应用于多值字段中的SAME值的那些项?
细节
我在Elasticsearch中存储了一些项目,这些项目的嵌套字段具有多个值,例如
"hits": [
{
"name": "John",
"tickets": [
{
"color": "green",
"code": "001"
},
{
"color": "red",
"code": "002"
}
]
},
{
"name": "Frank",
"tickets": [
{
"color": "red",
"code": "001"
},
{
"color": "green",
"code": "002"
}
]
}
]
现在考虑以下过滤器:
...
filter: [
{ terms: { 'tickets.code': '001' } },
{ terms: { 'tickets.color': 'green' } },
]
...
这两个项目都匹配,因为它们每个都至少有一个带有代码“001”的票证,并且每个都有一个带有“绿色”颜色的票证。
如何编写我的过滤器,以便只有第一个匹配项,因为它的票证的代码为“001”,颜色为“绿色”?
预先感谢您的任何建议。
最佳答案
您的问题是由Elasticsearch flattens objects引起的。因此,在内部,您的数据表示如下:
{
"name": "John",
"tickets.color": ["green", "red"],
"tickets.code": ["001", "002"]
},
{
"name": "Frank",
"tickets.color": ["red", "green"],
"tickets.code": ["001", "002"]
}
不可能知道同一对象上的颜色和代码。 (也存储了原始源,以便在您发出请求时返回,但这不是您搜索时查询的数据。)
这里有两种潜在的解决方案:denormalization或nested data type。如果您完全可以摆脱它,那么在这里非规范化是更好的选择,因为它更有效。如果对数据进行非规范化,则可能会得到如下所示的表示形式:
{
"name": "John",
"ticket": {
"color": "green",
"code": "001"
}
},
{
"name": "John",
"ticket": {
"color": "red",
"code": "002"
}
},
{
"name": "Frank",
"ticket": {
"color": "red",
"code": "001"
}
},
{
"name": , "Frank",
"ticket": {
"color": "green",
"code": "002"
}
}
如果使用嵌套数据类型,则必须使用类似以下的映射:
{
"ticket": {
"type": "nested",
"properties": {
"color": {"type": "keyword"},
"code": {"type": "keyword"}
}
}
}
关于elasticsearch - Elasticsearch:如何将多个过滤器应用于相同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47251402/