ElasticSearch从大量文档中选择不同的?

nafvub8i  于 2023-03-17  发布在  ElasticSearch
关注(0)|答案(3)|浏览(97)

我有一个索引,里面有大约1亿个文档。有时候我想检索所有文档,有时候我想按特定字段进行分组,为每个唯一值只选择一个文档。类似于:

SELECT * FROM documents GROUP BY my_field;

为了说明,有时我想得到:

|id|my_field|thing  |
|--|--------|-------|
|1 |a       |red    |
|2 |b       |yellow |
|3 |b       |green  |
|4 |c       |brown  |

有时候

|id|my_field|thing  |
|--|--------|-------|
|1 |a       |red    |
|3 |b       |green  |
|4 |c       |brown  |

ElasticSearch文档建议Terms Aggregation适用于此用途。然而,也有人建议这只适用于小基数的聚合术语,即少量的“buckets”:
有时候,单个请求/响应对中需要处理的唯一术语太多,因此将分析分解为多个请求可能会很有用
除此之外,Top Hits aggregation返回的数据格式看起来不容易分页。
比如说,如果我有一百万个不同的术语,我看起来它不会很好地与预期的设计对齐,对吗?
我的替代方法是在自己的代码中维护一个索引并标记重复项,但这很容易出错,并且会受到并发问题等的影响。
有没有一种方法来实现我想要的,发挥ElasticSearch的优势?

kulphzqa

kulphzqa1#

看起来这不是ElasticSearch索引/聚合的最佳用例。我用另一种方法解决了我的问题-创建一个单独的类型(或索引)来存储我的数据的去重视图。我使用唯一对的哈希作为_id字段,因此ElasticSearch在文档进入时自动去重。
作为一个额外的特性,使用外部_timestamp允许我选择在重复的情况下存储哪个文档。

vulvrdjw

vulvrdjw2#

现在在Elasticsearch中您可以使用composite aggregation

复合聚合开销很大。在生产环境中部署复合聚合之前,请先对应用程序进行负载测试。

从不同来源创建复合存储桶的多存储桶聚合。
与其他multi-bucket聚合不同,您可以使用composite聚合高效地对来自多级聚合的所有存储桶进行分页。此聚合提供了一种对特定聚合的所有存储桶进行流式传输的方法,类似于scroll对文档所做的操作。
复合存储桶是根据为每个文档提取/创建的值的组合构建的,每个组合都被视为一个复合存储桶。
你的问题提得有点晚了,但它可能对其他人有帮助。

4dc9hkyq

4dc9hkyq3#

我相信您的评估是正确的,虽然基数agg适合这里,但您可能遇到不同值的尺度会产生问题。This type of aggregation是我在ElasticSearch中所知道的最接近“GROUP BY”的东西。
话虽如此,我认为有一种方法可以
为每个唯一值仅选择一个文档。
通过嵌套在“Should”父项中的多个查询。
您的方法会有很大的不同,这取决于您的目标是只针对聚合计数还是返回值。
我最初的倾向是将您的请求视为嵌套在should中的一组兄弟查询。这种方法的问题是基于大多数匹配的字段返回,而不是每个不同查询的第一个文档。据我所知,对于每个bucket返回单个匹配的“should”查询,没有任何类型的评分。
为了返回文档,我相信您最适合执行multi-search

POST _msearch
{"index":"INDEX"}
{"query":{"match": {"a": "red"}},"size":1}
{"index":"INDEX"}
{"query":{"match": {"b": "yellow"}},"size":1}
{"index":"INDEX"}
{"query":{"match": {"b": "green"}},"size":1}

上面的代码将返回一个与每个查询匹配的文档,并给出一个带有“result”对象数组的响应。
原始计数:

POST /INDEX/_search
{
  "size": 0, 
  "aggs": {
    "a_red": {
      "filter": {
        "term": {
          "a": {
            "value": "red"
          }
        }
      }
    },        
    "b_yellow": {
      "filter": {
        "term": {
          "b": {
            "value": "yellow"
          }
        }
      }
    },        
    "b_green": {
      "filter": {
        "term": {
          "b": {
            "value": "green"
          }
        }
      }
    }
  }
}

注意:上例的聚合存储桶名称(例如:“a_red”)只是为了清楚起见,它们不是必需的。

相关问题