按用户折叠计算百分位数

qeeaahzv  于 2021-06-10  发布在  ElasticSearch
关注(0)|答案(1)|浏览(425)

假设我有一个索引,保存了一百万条tweets(原始对象)。我想根据关注者的数量得到90%的用户。我知道有一个聚合“百分位数”来做这个,但我的问题是,elasticsearch使用所有文档,所以我有一些用户发了很多tweet,他们干扰了我的计算。我想分离出所有唯一的用户,然后计算第90个。另一个限制是,我只想在一个或两个请求中这样做,以使响应低于500毫秒。
我试过很多方法,我可以用“脚本化的度量”来做到这一点,但是当我的数据集超过10万条tweet时,性能就会下降。
有什么建议吗?
附加信息:
我的索引存储基于用户搜索查询的原始tweets和retweets
索引Map为动态模板Map(这没有问题)
该指数约为100米
不幸的是,“热门”聚合不接受子聚合。
我想要达到的要求是:

{
  "collapse": {
    "field": "user.id"    <--- I want this effect on aggregation
  },
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "metadatas.clientId": {
              "value": projectId
            }
          }
        },
        {
          "match": {
            "metadatas.blacklisted": false
          }
        }
      ],
      "filter": [
        {
          "range": {
            "publishedAt": {
              "gte": "now-90d/d"
            }
          }
        }
      ]
    }
  },
  "aggs":{
    "twitter": {
      "percentiles": {
        "field": "user.followers_count",
        "percents": [95]
      }
    }
  },
  "size": 0
}
rjjhvcjd

rjjhvcjd1#

最后,我想出了一个解决办法。
在百分比聚合中,我可以使用脚本。我使用params变量保存唯一键,然后返回前面的\u分数。
没有对计算的完整解释,我无法微调脚本的行为。但结果对我来说已经足够好了。

"aggs": {
    "unique":{
      "cardinality": {
        "field": "collapse_profile"
      }
    },
    "thresholds":{
      "percentiles": {
        "field": "user.followers_count",
        "percents": [90], 
        "script": {
          "source": """
            if(params.keys == null){
              params.keys = new HashMap();
            }

            def key = doc['user.id'].value;
            def value = doc['user.followers_count'].value;

            if(params.keys[key] == null){
              params.keys[key] = _score;
              return value;
            }
            return _score;
          """,
          "lang": "painless"
        }
      }
    }    
  }

相关问题