Elasticsearch排序:每组一个,然后重复

时间:2018-07-09 05:58:40

标签: sorting elasticsearch

我需要从每个value获取最大为name的物品,并重复直到结束。

我将在一个简单的示例中对其进行解释。我有这样的物品:

Name| Value
-----------
AAA | 12
AAA | 35
AAA | 5
BBB | 1
BBB | 10
BBB | 5

排序后的预期结果:

Name| Value
-----------
AAA | 35
BBB | 10
AAA | 12
BBB | 5
AAA | 5
BBB | 1

我知道如何在Postgres中执行此操作(窗口功能:rank() over()),但是在Elastic中有可能吗?

3 个答案:

答案 0 :(得分:2)

  

您必须执行“最大分组”之类的操作

以下是示例

class PurchaseOrder(models.Model):
    _inherit = 'purchase.order'

    discount_warning_message = fields.Text(string='Discount Warning', compute='discount_warning')

     @api.depends('order_line.product_id', 'order_line.product_qty')
def discount_warning(self):
    qty_categ_total = 0.0
    for line in self.order_line:
        qty_categ_total +=  line.product_qty
        if qty_categ_total < line.product_id.categ_id.qty_for_discount:
            message = (_("You can get discount if you add %s more %s\n")) % (qty_categ_total, line.product_id.categ_id.name)
            self.discount_warning_message = message

参考:- this

答案 1 :(得分:1)

在这里汇总我的评论。

回答您的直接问题:不,据我所知不可能。但是,有一些Elasticsearch可以提供帮助的解决方法。

对于Elasticsearch而言,无论这些文档如何排序,显示超过100万条记录都是一个坏主意。有人问我在评论中的问题,以了解创建第二个ES索引是否合适,该结果可能是 1个查询+后处理并保存诸如“前1000条记录”(表示人类合理的文档列表)之类的内容,以及定期(每10秒左右)更新该列表。。您可以使用 Watcher 来建立此索引并保持更新。就像我说的那样,从ES的角度来看,一百万条记录既不切实际(他们将查看100万个文档),又表现不佳。

基本上,请保留一个单独的索引,该索引应仅包含根据您的要求排序的前1000个文档。而且该索引会定期更新,而不是包含100万个文档的主要索引。关于分页和100万。文档...您认为您的用户将浏览多少页? 10 15 15甚至google.com都不给您一切。即使有数以亿计的匹配项,也只有几十页。请记住,Elasticsearch是一个搜索引擎,而不是数据库。目的是为您提供最匹配的文档,而不是全部。

来自Watcher的查询将遍历主索引中的所有文档。它将根据您的要求汇总文档(我认为terms上的Name汇总,按Value排序),您可以添加post-processing step来创建所需的订单然后index that into a second index。下次手表触发时,它将删除旧索引,再次执行相同的查询,并将新结果索引到(现在为空)索引中。

答案 2 :(得分:0)

Elasticsearch支持按数组或多值字段排序。模式选项控制选择哪个数组值对它所属的文档进行排序。模式选项可以具有以下值:

min-选择最低值。

max-选择最高的值。

sum-使用所有值的总和作为排序值。仅适用于基于数字的数组字段。

avg-使用所有值的平均值作为排序值。仅适用于基于数字的数组字段。

median-使用所有值的中位数作为排序值。仅适用于基于数字的数组字段。

排序顺序: 订单选项可以具有以下值:

asc-以升序排序

desc-降序排列

下面是一个示例,其中字段价格每个文档具有多个价格。在这种情况下,结果命中将根据每个文档的平均价格按价格降序进行排序。

PUT /my_index/_doc/1?refresh
{
   "product": "chocolate",
   "price": [20, 4]
}

POST /_search
{
   "query" : {
      "term" : { "product" : "chocolate" }
   },
   "sort" : [
      {"price" : {"order" : "desc", "mode" : "avg"}}
   ]
}

嵌套排序示例 在下面的示例中,offer是一个嵌套类型的字段。需要指定嵌套路径;否则,Elasticsearch不知道需要捕获哪些嵌套级别的排序值。

POST /_search
{
   "query" : {
      "term" : { "product" : "chocolate" }
   },
   "sort" : [
       {
          "offer.price" : {
             "mode" :  "avg",
             "order" : "asc",
             "nested": {
                "path": "offer",
                "filter": {
                   "term" : { "offer.color" : "blue" }
                }
             }
          }
       }
    ]
}

有关详细说明和更多示例,请参见此链接Elastic search sort