elasticsearch-按百分比筛选

假设我要按第10到20个百分点内的某个字段过滤文档。我想知道是否可以通过一些简单的查询(例如)进行查询{"fieldName":{"percentile":

[0.1, 0.2]}}

说我有这些文件:

[{"a":1,"b":101},{"a":2,"b":102},{"a":3,"b":103}, ..., {"a":100,"b":200}]

我需要按a(升序)a 从前10位到第10位进行过滤b,然后按降序对结果进行排序,然后进行分页(如第2页,第10页)每页的项目)。

想到的一种解决方案是:

  1. 获取文件总数。

  2. 将文档按排序a,取对应_id的限制0.1 * total_count

  3. 写最终查询,像 id in (...) order by b

但是缺点也很明显:

  1. 如果我们谈论的是亚秒级延迟,则似乎效率不高

  2. 如果我们_id在第一个查询中返回的次数太多(第二个查询默认情况下,ES仅允许1000个,则第二个查询可能不起作用。我当然可以更改配置,但总会有一个限制)。

回答:

我怀疑如果a事先不知道的确切值,是否可以在一个查询中执行此操作,尽管我认为一种非常有效的方法是可行的。

我建议做一个percentiles聚合作为第一查询和第二range查询。

在我的样本索引中,我只有14个文档,因此出于说明性原因,我将尝试查找那些占字段30%到60%的文档,a并按b相反的顺序对它们进行排序(以确保排序有效)。

这是我插入的文档:

{"a":1,"b":101}

{"a":5,"b":105}

{"a":10,"b":110}

{"a":2,"b":102}

{"a":6,"b":106}

{"a":7,"b":107}

{"a":9,"b":109}

{"a":4,"b":104}

{"a":8,"b":108}

{"a":12,"b":256}

{"a":13,"b":230}

{"a":14,"b":215}

{"a":3,"b":103}

{"a":11,"b":205}

让我们找出a介于30%和60%百分位数之间的字段边界:

POST my_percent/doc/_search

{

"size": 0,

"aggs" : {

"percentiles" : {

"percentiles" : {

"field" : "a",

"percents": [ 30, 60, 90 ]

}

}

}

}

用我的样本索引看起来像这样:

{

...

"hits": {

"total": 14,

"max_score": 0,

"hits": []

},

"aggregations": {

"percentiles": {

"values": {

"30.0": 4.9,

"60.0": 8.8,

"90.0": 12.700000000000001

}

}

}

}

现在我们可以使用边界进行range查询:

POST my_percent/doc/_search

{

"query": {

"range": {

"a" : {

"gte" : 4.9,

"lte" : 8.8

}

}

},

"sort": {

"b": "desc"

}

}

结果是:

{

"took": 5,

"timed_out": false,

"_shards": {

"total": 5,

"successful": 5,

"skipped": 0,

"failed": 0

},

"hits": {

"total": 4,

"max_score": null,

"hits": [

{

"_index": "my_percent",

"_type": "doc",

"_id": "vkFvYGMB_zM1P5OLcYkS",

"_score": null,

"_source": {

"a": 8,

"b": 108

},

"sort": [

108

]

},

{

"_index": "my_percent",

"_type": "doc",

"_id": "vUFvYGMB_zM1P5OLWYkM",

"_score": null,

"_source": {

"a": 7,

"b": 107

},

"sort": [

107

]

},

{

"_index": "my_percent",

"_type": "doc",

"_id": "vEFvYGMB_zM1P5OLRok1",

"_score": null,

"_source": {

"a": 6,

"b": 106

},

"sort": [

106

]

},

{

"_index": "my_percent",

"_type": "doc",

"_id": "u0FvYGMB_zM1P5OLJImy",

"_score": null,

"_source": {

"a": 5,

"b": 105

},

"sort": [

105

]

}

]

}

}

注意percentiles聚合的结果是近似的。

通常,这看起来像是通过熊猫或Spark作业可以更好地解决的任务。

希望有帮助!

以上是 elasticsearch-按百分比筛选 的全部内容, 来源链接: utcz.com/qa/429897.html

回到顶部