首页 > 解决方案 > 如何聚合不同存储桶中的文档,然后将过滤器应用于结果

问题描述

我有很多这种格式的 elasticsearch 文档:

{
    "_index": "testIndex",
    "_type": "_doc",
    "_id": "0kt102sBt5sWDQMwsMNJ",
    "_score": 1.4376891,
    "_source": {
        "id": "8dJs76YI",
        "entity": "movie",
        "actor": "Pier",
        "action": "like",
        "source": "tablet",
        "tag": [
            "drama"
        ],
        "location": "3.698492,-73.697308",
        "country": "",
        "city": "",
        "timestamp": "2019-07-04T05:35:01Z"
    }
}

此索引存储针对movie实体执行的所有活动。idmovie身份证。actioncan be like, view, shareetc.actor是用户名。

我想应用聚合并获得那些总喜欢在 1000 到 10000 之间并且也被actorPier 喜欢但只有tags喜剧的电影。

查询需要结合 bool、terms 和 range 查询以及聚合。我已经尝试过过滤器聚合,但官方文档示例还不够。

任何人都可以举一些例子来为此准备查询。

谢谢。

标签: elasticsearch

解决方案


因此,我将开始使用不属于聚合的数据(即actorand )编写查询tag

{
    "query": {
        "bool": {
            "filter": [
                {
                    "term": {
                        "actor": "Pier"
                    }
                },
                {
                    "term": {
                        "tag": "comedy"
                    }
                },
                {
                    "term": {
                        "action": "like"
                    }
                }
            ]
        }
    }
}

这应该只过滤喜欢moviesPier演员阵容的一部分并且属于comedy类型。

接下来是聚合并获取每部电影的计数,因此使用terms聚合将所有内容按id.

{
    "query": {
        "bool": {
            "filter": [
                {
                    "term": {
                        "actor": "Pier"
                    }
                },
                {
                    "term": {
                        "tag": "comedy"
                    }
                },
                {
                    "term": {
                        "action": "like"
                    }
                }
            ]
        }
    },
    "aggs": {
        "movies": {
            "terms": {
                "field": "id",
                "min_doc_count": 1000
            }
        }
    }
}

所以有了这个查询,你应该已经有了每部电影的计数,因为我们已经过滤掉了,这些计数是针对 Pier 参与过的喜欢的喜剧电影,现在这必须过滤每个过滤器以确保想要的喜欢数量。

所以现在需要为每部电影添加最大喜欢。您需要为此使用存储桶选择器:

{
    "query": {
        "bool": {
            "filter": [
                {
                    "term": {
                        "actor": "Pier"
                    }
                },
                {
                    "term": {
                        "tag": "comedy"
                    }
                },
                {
                    "term": {
                        "action": "like"
                    }
                }
            ]
        }
    },
    "aggs": {
        "movieIds": {
            "terms": {
                "field": "id",
                "min_doc_count": 1000
            },
            "aggs": {
                "likesWithinRange": {
                    "bucket_selector": {
                        "buckets_path": {
                            "doc_count": "_count"
                        },
                        "script": {
                            "inline": "params.doc_count < 10000"
                        }
                    }
                }
            }
        }
    }
}

希望这有效,或者至少让你朝着正确的方向前进。


推荐阅读