Elasticsearch 数组只为聚合脚本提供唯一性

Elasticsearch array only gives uniques to aggregation script

我想在 Elasticsearch 中使用聚合中的脚本指标做一些简单的线性代数。我正在尝试使用数组类型来存储向量。我的问题是,在我的脚本中,我只收到数组中的一组唯一值,而不是具有原始排序的完整数组。有没有办法在脚本中获取原始数组?

考虑这个示例文档:

curl -XPUT 'http://localhost:9200/arraytest/aoeu/1' -d '{
    "items": [1, 2, 2, 3]
}'

_source 中看起来不错:

curl -XGET 'http://localhost:9200/arraytest/aoeu/1'

结果:

{"_index":"arraytest","_type":"aoeu","_id":"1","_version":1,"found":true,"_source":{
    "items": [1, 2, 2, 3]
}}

但是,当我在脚本中获取值时,它看起来不正确:

curl -XGET 'http://localhost:9200/arraytest/aoeu/_search?pretty&search_type=count' -d '{
    "query": {
        "match_all" : {}
    },
    "aggs": {
        "tails": {
            "scripted_metric": {
                "init_script": "_agg.items = []",
                "map_script": "_agg.items.add(doc.items)",
                "reduce_script": "items = []; for (a in _aggs) { items.add(a.items) }; return items"
            }
        }
    }
}'

结果:

{
  "took" : 103,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "tails" : {
      "value" : [ [ ], [ ], [ [ 1, 2, 3 ] ], [ ], [ ] ]
    }
  }
}

我原以为结果会包含 [1, 2, 2, 3],但结果却包含 [1, 2, 3]。我尝试在地图脚本中访问 _source,但它说没有这样的字段。

我在 a discussion about a different but related problem 的文档中发现了这个问题。内部对象的数组被展平以进行索引。这意味着内部对象(或其字段之一)的所有值的集合成为根文档上的数组。

可以指定一个嵌套的对象映射,而不是依赖动态映射,它索引内部文档的数组具有上述效果。然后,Elasticsearch 将不会展平内部文档数组,而是将它们分开存储并以一种使连接 "almost as fast" 如同将它们嵌入同一文档中的方式对它们进行索引。稍微玩了一下,我发现它使我的用例(不涉及连接)也很快(与为每个子文档创建单独的根文档相比)。

我认为这不能解决保留向量顺序的问题,因此我将在每个嵌套文档中包含索引。

映射示例:

curl -XPUT 'http://localhost:9200/arraytestnested' '{
    "mappings" : {
        "document" : {
            "properties" : {
                "some_property" : {
                    "type" : "string"
                },
                "items": {
                    "type": "nested",
                    "properties": {
                        "index" : {
                            "type" : "long"
                        },
                        "itemvalue" : {
                            "type" : "long"
                        }
                    }
                }
            }
        }
    }
}'