elasticsearch Elasticsearch多和聚合,elasticsearch,groovy,nosql,elasticsearch,Groovy,Nosql" /> elasticsearch Elasticsearch多和聚合,elasticsearch,groovy,nosql,elasticsearch,Groovy,Nosql" />

elasticsearch Elasticsearch多和聚合

elasticsearch Elasticsearch多和聚合,elasticsearch,groovy,nosql,elasticsearch,Groovy,Nosql,我们在每个索引(~10000)中都有大量文档。但每个文档都非常小,几乎只包含整数值 我们需要对所有的数值场求和 第一步-我们要求所有具有映射的可用字段 例如: GET INDEX/TYPE/_mapping GET INDEX/TYPE/_search { // SOME FILTERS TO REDUCE THE NUMBER OF DOCUMENTS "size":0, "aggs":{ "FIELD 1":{ "su

我们在每个索引(~10000)中都有大量文档。但每个文档都非常小,几乎只包含整数值

我们需要对所有的数值场求和

  • 第一步-我们要求所有具有映射的可用字段
  • 例如:

    GET INDEX/TYPE/_mapping
    
    GET INDEX/TYPE/_search
    {
        // SOME FILTERS TO REDUCE THE NUMBER OF DOCUMENTS
        "size":0,
        "aggs":{  
            "FIELD 1":{  
                "sum":{  
                    "field":"FIELD 1"
                }
            },
            "FIELD 2":{  
                "sum":{  
                    "field":"FIELD 2"
                }
            },
            // ...
            "FIELD N":{  
                "sum":{  
                    "field":"FIELD N"
                }
            }
        }
    }
    
  • 第二步-我们使用映射中的字段构建请求
  • 例如:

    GET INDEX/TYPE/_mapping
    
    GET INDEX/TYPE/_search
    {
        // SOME FILTERS TO REDUCE THE NUMBER OF DOCUMENTS
        "size":0,
        "aggs":{  
            "FIELD 1":{  
                "sum":{  
                    "field":"FIELD 1"
                }
            },
            "FIELD 2":{  
                "sum":{  
                    "field":"FIELD 2"
                }
            },
            // ...
            "FIELD N":{  
                "sum":{  
                    "field":"FIELD N"
                }
            }
        }
    }
    
    我们的问题是,第二个请求的执行时间与字段N的数量成线性关系

    这是不可接受的,因为这仅是总和。因此,我们尝试使用脚本化度量(groovy)生成我们自己的聚合

    仅包含两个字段的示例:

    // ...
    "aggs": {
        "test": {
            "scripted_metric": {
                "init_script": "_agg['t'] = []",
                "map_script": "_agg.t.add(doc)",
                "combine_script": "res = [:]; res['FIELD 1'] = 0; res['FIELD 2'] = 0; for (t in _agg.t) { res['FIELD 1'] += t.['FIELD 1']; res['FIELD 2'] += t.['FIELD 2']; }; return res", 
                "reduce_script": "res = [:]; res['FIELD 1'] = 0; res['FIELD 2'] = 0; for (t in _aggs) { res['FIELD 1'] += t.['FIELD 1']; res['FIELD 2'] += t.['FIELD 2']; }; return res"
            }
        }
    }
    // ...
    
    但是,我们在脚本中添加的做作越多,执行脚本所需的时间就越长,因此它并不能解决我们的问题

    没有太多的例子

    您有什么想法可以改进此脚本的性能吗?
    或者其他想法?

    它如何在次线性时间内计算N个和,是否存在这样的系统

    1000万份文件实际上并没有那么多。您的查询需要多长时间,您有多少个碎片,CPU的最大值是否为100%?(我本想在评论中问这些问题,但还没有50%的声誉)

    如果您对所有字段的总和感兴趣,可以在为文档编制索引时预先计算文档级别的总和,然后在查询时只取这些值的总和


    您还可以尝试将字段存储为,看看是否有帮助。您的内存压力和垃圾收集会更小,尽管文档中提到可能会有10-25%的性能损失。

    脚本通常成本较高。我看不出有什么理由在这里使用脚本。你不能使用总和指标聚合吗?你是什么意思?我们确实在所有字段上使用了总和聚合,它太慢了。为什么要使用脚本,使用这个-我们使用它(看看我的问题:步骤2)。但我们需要在许多文档字段上使用它。不确定这是否有帮助,但我会尝试将第一个请求拆分为多个请求,每个请求聚合一组字段。然后,我将使用批量请求来执行多个请求,您将不得不重复过滤器,尽管可能值得一试。