如何汇总不同存储桶中的文档,然后将过滤器应用于结果

时间:2019-07-20 18:03:27

标签: elasticsearch

我有许多这种格式的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的ID。 action可以是likeviewshare等。actor是用户的名称。

我想应用聚合并获得总喜欢在1000到10000之间并且actor皮尔也喜欢的电影,但只有那些tags作为喜剧的电影。

查询需要结合布尔,术语和范围查询以及聚合。我已经尝试过过滤器聚合,但是事实证明官方文档示例还不够。

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

谢谢。

1 个答案:

答案 0 :(得分:0)

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

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

这应该仅过滤喜欢的movies,其中Pier是演员表的一部分,属于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"
                        }
                    }
                }
            }
        }
    }
}

希望这样行得通,或者至少可以使您朝正确的方向前进。