2016-09-27 90 views
1

在「字段」中表示時,嵌套數組變得平坦。我期望來自相同路徑的值被合併,但內部數據結構不會被修改。如何防止Elasticsearch在「字段」中展平二維數組 - 包含查詢

有人可以解釋我是否做錯了什麼,或者這是否屬於Elasticsearch問題?

重現步驟:

  1. 創建2D數據

    curl -XPOST localhost:9200/test/5 -d '{ "data": [ [100],[2,3],[6,7] ] }' 
    
  2. 查詢數據,指定字段

    curl -XGET localhost:9200/test/5/_search -d '{"query":{"query_string":{"query":"*"} }, "fields":["data"] } }' 
    

    結果:

    {"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":1.0,"hits":[{"_index":"test","_type":"5","_id":"AVdsHJrepOClGTFyoGqo","_score":1.0,"fields":{"data":[100,2,3,6,7]}}]}} 
    
  3. 重複,而無需使用 「字段」 的:

    curl -XGET localhost:9200/test/5/_search -d '{"query":{"query_string":{"query":"*"} } } }' 
    

    結果:

    {"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":1.0,"hits":[{"_index":"test","_type":"5","_id":"AVdsHJrepOClGTFyoGqo","_score":1.0,"_source":{ "data": [ [100],[2,3],[6,7] ] }}]}} 
    

注意_source和字段不同,在 「場」 分解2D陣列成1D陣列。

回答

2

除了指定「領域」我平時做source filtering

您的查詢會更改爲類似的:

curl -XGET <IPADDRESS>:9200/test/5/_search -d '{"_source":{"include": ["data"]}, "query":{"query_string":{"query":"*"} }}' 
+0

安德烈,請解決這個問題的答案是:{ 「_source」:{ 「包括」: 「數據」}, 「查詢」:{ 「QUERY_STRING」:{ 「查詢」:「*」}}}'(缺少方括號。此外,雖然這提供了一個有用的演示,說明如何避免請求不必要的字段,但是您能否解釋爲什麼字段拼合2D數組?這是問題的一部分。 –

+0

@AlexeiKotlar - 我不知道爲什麼它會使數組變平,但Uli的帖子很有意義 - lucene將數組的數組作爲平面數組索引,因此當您指定'field' request屬性時,lucene只能檢索到平面版本 我們都有完整的答案,請標記你感覺更有用:) – Andrey

3

當您在請求中指定沒有別的,你什麼時候回來的foreach衝擊最大的是「_source」對象,即恰恰是您在編制索引期間發送給ES的Json(甚至包括空格!)。

當您使用源過濾時,正如安德烈所建議的那樣,除了您可以包含或排除某些字段外,它是相同的。

當您在查詢中使用「fields」指令時,返回值不會從_source中獲取,而是直接從Lucene索引中讀取。 (請參閱docs)現在,搜索響應中的鍵將從「_source」切換到「字段」以反映此更改。

作爲鹼說: https://www.elastic.co/guide/en/elasticsearch/reference/current/array.html 這些文件說,前面說,是的,Elasticsearch確實平坦陣列。

+0

我在第二個例子中很愚蠢,我可能只是說領域和_source領域不同,因爲二維數組是平坦的。我想你的答案几乎就在那裏。 lucene是否尊重2D數組? –

+0

這是關於ES內部的一個很好的回答! – alkis

2

從這裏https://www.elastic.co/guide/en/elasticsearch/reference/current/array.html 看來elasticsearch認爲它們是一樣的。

In Elasticsearch, there is no dedicated array type. Any field can contain zero or more values by default, however, all values in the array must be of the same datatype. For instance: 

an array of strings: [ "one", "two" ] 
an array of integers: [ 1, 2 ] 
an array of arrays: [ 1, [ 2, 3 ]] which is the equivalent of [ 1, 2, 3 ] 
an array of objects: [ { "name": "Mary", "age": 12 }, { "name": "John", "age": 10 }] 

你可以使用JSON對象的數組,並使用嵌套的數據類型與嵌套查詢。

也許嵌套的數據類型可能會有所幫助

PUT /my_index 

PUT /my_index/_mapping/my_type 
{ 
    "properties" : { 
     "data" : { 
     "type" : "nested", 
      "properties": { 
      "value" : {"type": "long" } 
     } 
     } 
    } 
} 

POST /my_index/my_type 
{ 
    "data": [ 
    { "value": [1, 2] }, 
    { "value": [3, 4] } 
    ] 
} 

POST /my_index/my_type 
{ 
    "data": [ 
    { "value": [1, 5] } 
    ] 
} 

GET /my_index/my_type/_search 
{ 
    "query": { 
    "nested": { 
     "path": "data", 
     "query": { 
     "bool": { 
      "must": [ 
      { 
       "match": { 
       "data.value": 1 
       } 
      }, 
      { 
       "match": { 
       "data.value": 2 
       } 
      } 
      ] 
     } 
     } 
    } 
    } 
} 
+0

謝謝,這回答了問題的「原因」。然而,它並沒有像Andrey那樣提供一個好的解決方案,因爲嵌套查詢迫使我大大改變數據映射的方式。它們似乎用於相關集合(不管是否與其他東西並存)。在我的用例中,數組具有不同的含義:跨字段值存儲在數組中以表示相同的關係;要使用嵌套地圖複製這個,我需要將我的索引大小加倍,這很荒謬。我會接受這個答案,如果我們可以信任@Andrey的實際解決方案。 –

+0

沒有理由不選擇爲您提供解決方案的答案(Andrey在這種情況下)。我同意嵌套不適合你的用例。 upvote,更重要的是你的有趣用例和提供的解決方案對我來說已經足夠了。玩得開心 – alkis

+0

太棒了。我很感謝你的回答,這對我對這個問題的理解很有價值。謝謝! –

相關問題