【问题标题】:Sort elasticsearch aggregation buckets by text field按文本字段对弹性搜索聚合桶进行排序
【发布时间】:2020-02-21 17:15:12
【问题描述】:

我正在尝试对 elasticsearch 聚合的结果桶进行排序。 我有一大堆文件:

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

我目前正在做的是使用 compositetop_hits 聚合获取每个 product_id 的最新销售:

{
    "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。

【问题讨论】:

    标签: elasticsearch elasticsearch-aggregation


    【解决方案1】:

    来自文档

    每个桶可以根据其_key、_count或其子聚合进行排序

    您可以使用 product_name.keyword 来代替产品 ID 聚合并按键排序

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

    【讨论】:

    • 您的意思是composite 聚合中的“条款”查询?这将按 product_name 而不是 product_id 生成不同的存储桶(完全改变查询结果)。此外,我有更多的文本字段,而不仅仅是 product_name,我希望能够将它们中的任何一个用作最终排序字段。
    • top_hits 聚合中的值无法访问以进行进一步聚合。您需要在客户端进行排序
    • 谢谢,我担心我不得不退回到客户端排序。是否有任何聚合应用于只有一个文档的存储桶会返回该文档的任意字段?
    猜你喜欢
    • 2016-06-04
    • 2015-12-30
    • 2019-02-18
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 2019-08-31
    相关资源
    最近更新 更多