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"
}
}
}
}
}
}
}'
我想在 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"
}
}
}
}
}
}
}'