我是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"}}
}
}
然后使用response的aggregations.user_ids.buckets.key
获取匹配用户的列表。
然而,这个列表似乎只是简单地按文档数排序(因此,如果用户有两个包含单词“test”的帖子,他们似乎会赢得名为“test”的用户的支持),我想尝试一下排序。我目前的想法是使用平均(或中值)文档匹配_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
值。如果这样可以的话-有没有办法“禁用”它们并只返回聚合?
3条答案
按热度按时间mv1qrgav1#
使用以下查询
m1m5dgzv2#
我想我找到了一个对聚合进行排序的解决方案。我必须创建一个子聚合,然后它就工作了。我错了,试图使用
"order": {"_score: "desc"}
和类似的废话,而那里没有任何_score
(那是文档的集合,而不是文档,所以那里没有得分)。有了这个,我的
aggregations
看起来就像我想要的:但是,关于是否具有
hits
(我不使用它)的问题仍然存在。e5nszbig3#
帖子的答案很棒,只是有一件小事要提一下。
我觉得我做错的另一件事是我根本不使用hits--我只是不需要它们--只使用聚合的user_id值。如果这没问题--有没有办法“禁用”它们,只返回聚合?
要实现这一点,只需使用“size”:“查询”字段中的0。