按文本字段对Elasticsearch聚合存储桶进行排序

时间:2019-10-25 10:44:40

标签: elasticsearch elasticsearch-aggregation

我正在尝试对Elasticsearch聚合的结果存储桶进行排序。 我有很多文件:

"mappings": {
    "properties": {
        "price": {
            "type": "double"
        },
        "product_name": {
            "type": "text"
        },
        "product_id": {
            "type": "keyword"
        },
        "timestamp": {
            "type": "date"
        }
    }
}

我目前正在做的是使用product_idcomposite聚合获取每个top_hits的最新卖出:

{
    "query": {
        "bool": {
            "filter": [
                {
                    "range": {
                        "timestamp": {
                            "gte": "2019-10-25T00:00:00Z",
                            "lte": "2019-10-26T00:00:00Z"
                        }
                    }
                }
            ]
        }
    },
    "aggs": {
        "distinct_products": {
            "composite": {
                "sources": [
                    {
                        "distinct_ids": {
                            "terms": {
                                "field": "product_id"
                            }
                        }
                    }
                ],
                "size": 10000
            },
            "aggs": {
                "last_timestamp": {
                    "top_hits": {
                        "sort": {
                            "timestamp": {
                                "order": "desc"
                            }
                        },
                        "size": 1
                    }
                }
            }
        }
    }
}

现在,我想按任意字段对结果存储区进行排序。 如果我想按price进行排序,则可以使用this question中的解决方案 通过添加一个max聚合来从每个存储桶中提取product_price字段,最后添加一个bucket_sort聚合来对max的结果进行排序:

{
    "query": {
        "bool": {
            "filter": [
                {
                    "range": {
                        "timestamp": {
                            "gte": "2019-10-25T00:00:00Z",
                            "lte": "2019-10-26T00:00:00Z"
                        }
                    }
                }
            ]
        }
    },
    "aggs": {
        "distinct_products": {
            "composite": {
                "sources": [
                    {
                        "distinct_ids": {
                            "terms": {
                                "field": "product_id"
                            }
                        }
                    }
                ],
                "size": 10000
            },
            "aggs": {
                "last_timestamp": {
                    "top_hits": {
                        "sort": {
                            "timestamp": {
                                "order": "desc"
                            }
                        },
                        "size": 1,
                        "_source": {
                            "excludes": []
                        }
                    }
                },
                "latest_sell": {
                    "max": {
                        "field": "product_price"
                    }
                },
                "latest_sell_secondary": {
                    "max": {
                        "field": "timestamp"
                    }
                },
                "sort_sells": {
                    "bucket_sort": {
                        "sort": {
                            "latest_sell": {
                                "order": "desc"
                            },
                            "latest_sell_secondary": {
                                "order": "desc"
                            }
                        },
                        "from": 0,
                        "size": 10000
                    }
                }
            }
        }
    }
}

如果我想按product_name而不是product_price的字母顺序进行排序,则我不能使用max聚合,因为它仅适用于数字字段。

如何通过文本字段对last_timestamp个存储桶(每个存储桶只有一个文档)进行排序?

我正在使用的Elasticsearch版本是7.2.0。

1 个答案:

答案 0 :(得分:1)

来自文档

  

每个存储桶都可以根据其_key,_count或其子集合进行排序

您可以使用product_name.keyword而不是产品ID进行术语汇总并按键排序

"order": { "_key" : "asc" }