我正在寻找一种在弹性搜索中进行精确数组匹配的方法。 让我们说这些是我的文件:
{"id": 1, "categories" : ["c", "d"]}
{"id": 2, "categories" : ["b", "c", "d"]}
{"id": 3, "categories" : ["c", "d", "e"]}
{"id": 4, "categories" : ["d"]}
{"id": 5, "categories" : ["c", "d"]}
有没有办法搜索所有完全类别“c”和“d”(文档1和5)的文档,不多或少?
作为奖励:仍然可以搜索“其中一个”类别(例如,您可以搜索“c”并获得1,2,3和5)
有什么聪明的方法可以解决这个问题吗?
答案 0 :(得分:19)
如果您有一组离散的已知类别,则可以使用bool查询:
"bool" : {
"must" : {
"terms" : { "categories" : ["c", "d"],
minimum_should_match : 2
}
},
"must_not" : {
"terms" : { "categories" : ["a", "b", "e"],
minimum_should_match : 1
}
}
}
否则,我认为,实现这一目标的最简单方法可能是存储另一个作为类别关键字的字段。
{"id": 1, "categories" : ["c", "d"], "categorieskey" : "cd"}
这样的事情。然后,您可以使用术语查询轻松查询所需的结果,例如:
term { "categorieskey" : "cd" }
你仍然可以非专有地搜索,因为;
term { "categories" : "c" }
查询必须同时存在的两个类别很容易,但是防止任何其他潜在类别出现更加困难。你可以这么做。您可能希望编写查询以查找包含这两者的记录,然后对其应用过滤器,从而消除除指定类别之外的任何类别的记录。据我所知,这并不是Lucene真正想要处理的那种搜索。
老实说,我在这里使用一个好的过滤器时遇到了一些麻烦。您可能需要脚本过滤器,或者可以在检索结果后过滤结果。
答案 1 :(得分:1)
我找到了一个似乎有效的用例解决方案。它依赖于两个过滤器以及我们想要匹配的类别数量的知识。我们使用术语过滤器和脚本过滤器来检查数组的大小。在此示例中,marketBasketList与您的类别条目类似。
{
"query": {
"bool": {
"must": [
{
"match": {
"siteId": 4
}
},
{
"match": {
"marketBasketList": {
"query": [
10,
11
],
"operator": "and"
}
}
}
]
},
"boost": 1,
"filter": {
"and": {
"filters": [
{
"script": {
"script": "doc['marketBasketList'].values.length == 2"
}
},
{
"terms": {
"marketBasketList": [
10,
11
],
"execution": "and"
}
}
]
}
}
}
}