📜  弹性搜索 |查询和过滤器的区别(1)

📅  最后修改于: 2023-12-03 15:39:32.411000             🧑  作者: Mango

弹性搜索:查询和过滤器的区别

Elasticsearch是一个功能强大的开源搜索引擎,用于实时搜索和分析大量数据。在弹性搜索中,查询和过滤器是弹性搜索中两个主要的搜索工具。虽然他们都可以根据给定条件返回匹配的文档,但两者之间有一些重要的不同点,该如何正确使用并理解这些不同点,是每位程序员在使用弹性搜索时必须掌握的技能。

查询(Query)

Query适用于在Lucene索引上执行全文搜索,用户在搜索时输入关键词,内部会根据算法来计算每个文档的相关度,并将查询词与文档内容进行匹配。Query中支持多种查询方式,如:

  • 精确查询:term和terms
  • 区间查询:range
  • 前缀查询:prefix
  • 映射查询:match和multi_match
  • 模糊查询:fuzzy
  • 正则表达式查询:regexp
  • 近似短语匹配查询:match_phrase
  • 成对出现查询:span_near, span_first, span_not
  • ......

以上只是部分查询方式的示例, Query具有强大的搜索能力,但也有一些缺点。它们使用的分数算法通常很奇怪,因此可能需要很长时间来调整算法参数,以获取预期的搜索结果。通常,搜索结果排序是基于相关性评分评估的,因此,Query可能会将不太相关的结果排在较优秀的结果之前。

过滤器(Filter)

过滤器是一种不能修改全局搜索结果的查询方式。与Query不同,过滤器返回对查询符合条件的文档进行缓存和重新利用的不可变结果。一旦过滤器被构建,它们就可以容易地在索引中重复使用或通过任何其他查询进行优化。Elasticsearch提供了多种可以使用的过滤器,如:

  • 精确值过滤器:term和terms
  • 区间过滤器:range
  • 前缀过滤器:prefix
  • 存在过滤器:exists
  • 布尔过滤器:bool
  • 地理位置过滤器:geo_bounding_box, geo_distance, geo_shape
  • .....

使用过滤器非常快,因为它们已经针对列出的缓存进行了优化。它们不占用评分因素,这为CPU节省时间和资源,大大提高搜索效率。但过滤器有一个主要缺点:它们会给遵循某些筛选条件的文档返回相同的分数。因此,在默认情况下,Elasticsearch使用与无过滤式查询相同的排序和返回文档停用词。

例子:

下面是一个查询和过滤器在Elasticsearch中的实际比较:

查询
{
    "query": {
        "bool": {
            "must": {
                "match": {"title": "elasticsearch"}
            },
            "filter": {
                "range": {"year": {"gte": 2010}}
            }
        }
    }
}

此查询表示文档的标题必须包含单词“elasticsearch”,而且过去十年内(即从2010年开始)创建的文档才会被返回。查询将返回最相关的搜索结果(即评分最高的结果)。

过滤器
{
    "query": {
        "bool": {
            "must": {
                "match": {"title": "elasticsearch"}
            },
            "filter": [
                {"range": {"year": {"gte": 2010}}}
            ]
        }
    }
}

在这种情况下,“filter”被用作一个过滤器来限制返回的文档。因此,搜索结果将不会根据相对文件的相关程度排序,而是只返回符合过滤器的文档,且对这些文档进行排序