查询和过滤上下文

查询和过滤上下文 #

查询由查询子句组成,这些子句可以在过滤(filter)上下文或查询上下文中运行。 在过滤(filter)上下文中的查询子句会询问“文档是否匹配查询子句?”并返回匹配的文档。在查询上下文中的查询子句会询问“文档与查询子句匹配程度如何?”,返回匹配的文档,并以相关性分数的形式提供每个文档的相关性。

相关性分数 #

相关性分数衡量文档与查询的匹配程度。它是一个正浮点数,Easysearch 会记录在每个文档的 _score 元数据字段中:

"hits" : [
      {
        "_index" : "shakespeare",
        "_id" : "32437",
        "_score" : 18.781435,
        "_source" : {
          "type" : "line",
          "line_id" : 32438,
          "play_name" : "Hamlet",
          "speech_number" : 3,
          "line_number" : "1.1.3",
          "speaker" : "BERNARDO",
          "text_entry" : "Long live the king!"
        }
      },
...

一个更高的分数表示文档更相关。虽然不同的查询类型计算相关性分数的方式不同,但所有查询类型都会考虑查询子句是在过滤(filter)上下文还是查询上下文中运行。

在查询上下文中使用你想影响相关性分数的查询子句,并在过滤(filter)上下文中使用所有其他查询子句。

过滤上下文 #

在过滤上下文中的查询子句会问“文档是否匹配查询子句?”,这个问题有二元答案。例如,如果你有一个包含学生数据的索引,你可以使用过滤上下文来回答以下关于学生的疑问:

  • 学生的 honors 状态是否设置为 true ?
  • 学生的 graduation_year 是否在 2020–2022 范围内?

使用过滤上下文时,Easysearch 会返回匹配的文档,而不会计算相关性分数。因此,您应该使用过滤上下文来处理具有精确值的字段。

要在过滤上下文中运行查询子句,请将其传递给 filter 参数。例如,以下布尔查询会搜索在 2020–2022 年获得荣誉学位的学生:

GET students/_search
{
  "query": {
    "bool": {
      "filter": [
        { "term":  { "honors": true }},
        { "range": { "graduation_year": { "gte": 2020, "lte": 2022 }}}
      ]
    }
  }
}

为了提高性能,Easysearch 会缓存常用的过滤器。

查询上下文 #

查询上下文中的查询子句会询问“文档与查询子句的匹配程度如何?”,这个问题没有二元答案。查询上下文适用于全文搜索,你不仅希望获得匹配的文档,还希望确定每个文档的相关性。例如,如果你有一个包含莎士比亚全部作品的索引,你可以使用查询上下文进行以下搜索:

  • 查找包含单词 dream 的文档,包括其各种形式( dreamingdreams )和同义词( contemplate )。
  • 找到匹配 long live king 单词的文档。

使用查询上下文时,每个匹配的文档在 _score 字段中包含一个相关性分数,你可以用它来按相关性排序文档。

要在查询上下文中运行查询子句,将其传递给 query 参数。例如,以下查询在 shakespeare 索引中搜索匹配 long live king 单词的文档:

GET shakespeare/_search
{
  "query": {
    "match": {
      "text_entry": "long live king"
    }
  }
}

相关性分数是单精度浮点数,具有 24 位尾数精度。如果分数计算超过尾数精度,可能会发生精度损失。