Elasticsearch订单字词按得分

时间:2017-05-11 17:27:31

标签: sorting search elasticsearch aggregation relevance

我是ElasticSearch的新手。以前我只在Django-Haystack中使用它,时间非常有限,而且从未直接与ES交谈。

目前,我有一个带有一些文档的ElasticSearch(5.x,如果这很重要)索引。我使用的是Python + elasticsearch-dsl + django-elasticsearch-dsl所以我正在为数据库模型编制索引,但它并不重要。我试着让这个问题与图书馆无关。

从概念上讲,我将用户及其帖子存储在同一个索引中。用户和帖子的文档有一个共同点 - 字段user_id

用户看起来像这样:

{
    "_id": 1,
    "_type": "user_document",
    "username": "jdoe",
    "user_id": 1,
    "title": "Test user"
}

帖子是这样的:

{
    "_id": 1,
    "_doc": "post_document",
    "user_id": 1,
    "title": "Hello world!",
    "text": "Lorem ipsum test test test..."
}

我希望我的应用实现的是一个单输入搜索字段,对用户及其帖子进行全文搜索(在现实世界中有更多文档"类型" - 我'这里简化了一些事情,仅用于示例目的)。我希望按user_id汇总,以显示已匹配的不同用户的列表。

目前,我正在做这样的查询:

{
    "query": {
        "multi_match": {
            "query": "test",
            "fields": ["username^3", "title^2", "text"]
        }
    },
    "aggs": {
        "user_ids": {"terms": {"field": "user_id"}}
    }
}

然后使用响应aggregations.user_ids.buckets.key获取匹配用户列表。

然而,该列表似乎只是按文档计数排序(因此,如果用户有一对帖子,其中包含" test"他们似乎赢得了名为&#34的用户;测试&#34 ;),我想尝试订购。我目前的想法是使用平均(或中值)文档匹配_score

注意:在实际情况中,不仅仅有两种文档类型,因此使用快捷方式并仅查询特定_type的文档类型。

我该怎么做?我正在阅读"Sorting by a Metric"章节,但有些想法在我身上丢失了。我做了几次尝试,但基本上都是胡说八道。任何人都可以请出示一个具体的查询示例(最好是解释它是如何构建的),所以我可以从中学习吗?

以下是Gist with an example dataset,上面显示的搜索查询以及我得到的确切结果。我想要的(在test_query_01_results.json中)是将user_id 1优先于2,其逻辑为2.0794415> (0.78306973 + 0.45315093)/ 2.

我觉得我做错的另一件事是,我根本不使用hits - 我只是不需要它们 - 只有汇总的user_id值。如果这没关系 - 有没有办法去"禁用"他们只返回聚合?

1 个答案:

答案 0 :(得分:5)

使用以下查询

{
"size": 0 ,                    ==> to return no hits
"query": {                     ==> query similar to yours
    "multi_match": {
        "query": "test",
        "fields": ["username^3", "title^2", "text"]
    }
},
"aggs": {
    "user_ids": {
        "terms": {
            "field": "user_id",
            "order": {"avg_score": "desc"}
        },
        "aggs": {
            "avg_score": {
                "avg": {"script": "_score"}
              }
          }
      }
    }
  }