2015-04-02 30 views
0

我想在聚合中使用腳本度量在Elasticsearch中做一些簡單的線性代數。我正在嘗試使用數組類型來存儲矢量。我的問題是,在我的腳本中,我只接收來自數組的唯一值集合,而不是具有原始排序的完整數組。有沒有辦法在腳本中獲取原始數組?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,但它說沒有這樣的字段。

回答

1

我在文檔中發現了這個問題,在a discussion about a different but related problem。內部物體的數組被平坦化以進行索引。這意味着內部對象(或其某個字段)的所有值的集合成爲根文檔上的數組。

可以指定一個嵌套的對象映射,而不是依靠動態映射來索引內部文檔數組。然後,Elasticsearch不會將內部文檔數組變大,而是將它們分開存儲並將它們編入索引,從而使聯接「幾乎與同一個文檔中嵌入的速度一樣快」。經過一番努力,我發現它使得我的用例(不涉及連接)快速(與爲每個子文檔創建單獨的根文檔相比)。

我不認爲這解決了保存向量的順序,所以我會在每個嵌套文檔中包含索引。

實施例的映射:

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