查询和过滤上下文编辑

相关性评分编辑

默认情况下,Elasticsearch 按 相关性评分 对匹配的搜索结果进行排序,该评分衡量每个文档与查询的匹配程度。

相关性评分是一个正浮点数,在 搜索 API 的 _score 元数据字段中返回。 _score 越高,文档的相关性越高。虽然每种查询类型都可以采用不同的方式计算相关性评分,但评分计算还取决于查询子句是在 查询 上下文中运行还是在 过滤 上下文中运行。

查询上下文编辑

在查询上下文中,查询子句回答了“*此文档与该查询子句的匹配程度如何?*”这个问题。除了决定文档是否匹配之外,查询子句还会在 _score 元数据字段中计算相关性评分。

每当将查询子句传递给 query 参数(例如 搜索 API 中的 query 参数)时,查询上下文都会生效。

过滤上下文编辑

在过滤上下文中,查询子句回答了“*此文档是否与该查询子句匹配?*”这个问题。答案是简单的“是”或“否”——不计算评分。过滤上下文主要用于过滤结构化数据,例如:

  • timestamp 是否介于 2015 年到 2016 年之间?
  • status 字段是否设置为 "published"?

Elasticsearch 会自动缓存经常使用的过滤器,以提高性能。

每当将查询子句传递给 filter 参数(例如 bool 查询中的 filtermust_not 参数、constant_score 查询中的 filter 参数或 filter 聚合)时,过滤上下文都会生效。

查询和过滤上下文示例编辑

以下是 search API 中在查询和过滤上下文中使用查询子句的示例。此查询将匹配满足以下所有条件的文档:

  • title 字段包含单词 search
  • content 字段包含单词 elasticsearch
  • status 字段包含确切的单词 published
  • publish_date 字段包含 2015 年 1 月 1 日以后的日期。
$params = [
    'body' => [
        'query' => [
            'bool' => [
                'must' => [
                    [
                        'match' => [
                            'title' => 'Search',
                        ],
                    ],
                    [
                        'match' => [
                            'content' => 'Elasticsearch',
                        ],
                    ],
                ],
                'filter' => [
                    [
                        'term' => [
                            'status' => 'published',
                        ],
                    ],
                    [
                        'range' => [
                            'publish_date' => [
                                'gte' => '2015-01-01',
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],
];
$response = $client->search($params);
resp = client.search(
    body={
        "query": {
            "bool": {
                "must": [
                    {"match": {"title": "Search"}},
                    {"match": {"content": "Elasticsearch"}},
                ],
                "filter": [
                    {"term": {"status": "published"}},
                    {"range": {"publish_date": {"gte": "2015-01-01"}}},
                ],
            }
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      bool: {
        must: [
          {
            match: {
              title: 'Search'
            }
          },
          {
            match: {
              content: 'Elasticsearch'
            }
          }
        ],
        filter: [
          {
            term: {
              status: 'published'
            }
          },
          {
            range: {
              publish_date: {
                gte: '2015-01-01'
              }
            }
          }
        ]
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "bool": {
	      "must": [
	        {
	          "match": {
	            "title": "Search"
	          }
	        },
	        {
	          "match": {
	            "content": "Elasticsearch"
	          }
	        }
	      ],
	      "filter": [
	        {
	          "term": {
	            "status": "published"
	          }
	        },
	        {
	          "range": {
	            "publish_date": {
	              "gte": "2015-01-01"
	            }
	          }
	        }
	      ]
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  body: {
    query: {
      bool: {
        must: [
          {
            match: {
              title: 'Search'
            }
          },
          {
            match: {
              content: 'Elasticsearch'
            }
          }
        ],
        filter: [
          {
            term: {
              status: 'published'
            }
          },
          {
            range: {
              publish_date: {
                gte: '2015-01-01'
              }
            }
          }
        ]
      }
    }
  }
})
console.log(response)
GET /_search
{
  "query": { 
    "bool": { 
      "must": [
        { "match": { "title":   "Search"        }},
        { "match": { "content": "Elasticsearch" }}
      ],
      "filter": [ 
        { "term":  { "status": "published" }},
        { "range": { "publish_date": { "gte": "2015-01-01" }}}
      ]
    }
  }
}

query 参数指示查询上下文。

bool 和两个 match 子句在查询上下文中使用,这意味着它们用于对每个文档的匹配程度进行评分。

filter 参数指示过滤上下文。其 termrange 子句在过滤上下文中使用。它们将过滤掉不匹配的文档,但不会影响匹配文档的评分。

为查询上下文中查询计算的评分表示为单精度浮点数;它们只有 24 位用于表示有效数字的精度。超过有效数字精度的评分计算将转换为浮点数,并会损失精度。

对于应影响匹配文档评分的条件(即文档的匹配程度),请在查询上下文中使用查询子句,并在过滤上下文中使用所有其他查询子句。