使用elasticsearch在数组对象类型中进行精确搜索

pau*_*kul 17 lucene elasticsearch

我正在寻找一种在弹性搜索中进行精确数组匹配的方法.让我们说这些是我的文件:

{"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"]}
Run Code Online (Sandbox Code Playgroud)

有没有办法搜索具有完全类别"c"和"d"(文档1和5)的所有文档,不多或少?

作为奖励:仍然可以搜索"其中一个"类别(例如,您可以搜索"c"并获得1,2,3和5)

有什么聪明的方法可以解决这个问题吗?

fem*_*gon 19

如果您有一组离散的已知类别,则可以使用bool查询:

"bool" : {
    "must" : {
        "terms" : { "categories" : ["c", "d"],
             minimum_should_match : 2
         }
    },
    "must_not" : {
        "terms" : { "categories" : ["a", "b", "e"],
             minimum_should_match : 1
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

否则,我认为,实现此目标的最简单方法可能是存储另一个作为类别关键字的字段.

{"id": 1, "categories" : ["c", "d"], "categorieskey" : "cd"}
Run Code Online (Sandbox Code Playgroud)

这样的事情.然后,您可以使用术语查询轻松查询您想要的结果,例如:

term { "categorieskey" : "cd" }
Run Code Online (Sandbox Code Playgroud)

你仍然可以非专有地搜索,因为;

term { "categories" : "c" }
Run Code Online (Sandbox Code Playgroud)

查询必须同时存在的两个类别是很容易的,但是防止任何其他潜在类别存在更加困难.你可以这么做.您可能希望编写查询以查找包含这两者的记录,然后对其应用过滤器,从而消除除指定类别之外的任何类别的记录.据我所知,这并不是Lucene真正想要处理的那种搜索.

老实说,我在这里使用一个好的过滤器时遇到了一些麻烦.您可能需要脚本过滤器,或者可以在检索结果后过滤结果.