2015-05-17 74 views
1

我有許多索引文件如此一:ElasticSearch:檢索字符串連接,或部分陣列

{ 
    "_index":"myindex", 
    "_type":"somedata", 
    "_id":"31d3255d-67b4-40e6-b9d4-637383eb72ad", 
    "_version":1, 
    "_score":1, 
    "_source":{ 
     "otherID":"b4c95332-daed-49ae-99fe-c32482696d1c", 
     "data":[ 
     { 
      "data":"d2454d41-a74e-43af-b3b0-0febeaf67a99", 
      "iD":"9362f2eb-9bd7-4924-8b0e-77c27bb0aa56" 
     }, 
     { 
      "data":"some text", 
      "iD":"c554b8ce-c873-4fef-b306-ec65d2f40394" 
     }, 
     { 
      "data":"5256983c-ef69-4363-9787-97074297c646", 
      "iD":"8c90e2be-6042-4450-b0fd-0732900f8f65" 
     }, 
     { 
      "data":"other text", 
      "iD":"8d8f8a61-02d6-4d3e-9912-9ebb5d213c15" 
     }, 
     { 
      "data":"3", 
      "iD":"c880bfdf-eb4b-4c80-9871-fd44e06b2ed2" 
     } 
     ], 
     "iD":"31d3255d-67b4-40e6-b9d4-637383eb72ad" 
    } 
} 

它類型的映射被配置是這樣的:

{ 
    "somedata":{ 
     "dynamic_templates":[ 
     { 
      "defaultIDs":{ 
       "match_pattern":"regex", 
       "mapping":{ 
        "index":"not_analyzed", 
        "type":"string" 
       }, 
       "match":".*(id|ID|iD)" 
      } 
     } 
     ], 
     "properties":{ 
     "otherID":{ 
      "index":"not_analyzed", 
      "type":"string" 
     }, 
     "data":{ 
      "properties":{ 
       "data":{ 
        "type":"string" 
       }, 
       "iD":{ 
        "index":"not_analyzed", 
        "type":"string" 
       } 
      } 
     }, 
     "iD":{ 
      "index":"not_analyzed", 
      "type":"string" 
     } 
     } 
    } 
} 

我希望能夠根據它的ID檢索數據的字符串連接。
例如,如果ID爲c554b8ce-c873-4fef-b306-ec65d2f40394,並且ID爲8d8f8a61-02d6-4d3e-9912-9ebb5d213c15,我想檢索some text other text
這些ID在具有不同數據的相同類型的其他文檔中重複。

如果這是不可能的(我懷疑是這種情況),我想至少檢索一個包含我請求的數據的部分數組。
這些數組可能會變大(文檔數量也是如此),我只需要每次擊中一個或兩個元素。

如果我的要求都不可行,您如何建議更改我的映射以便於我的需求?

在此先感謝喬納森。

回答

3

我發現了一種方法來做剛好我所需要的而不改變我的數據結構。
(我實際上最終改變了我的數據結構,但由於空間和效率的原因)。

所有你需要做的就是享受常規善良 ElasticSearch必須提供:

{ 
    "query" : { "term" : { "otherID" : "b4c95332-daed-49ae-99fe-c32482696d1c" } }, 
    "script_fields" : { "requestedFields" : { "script" : "_source.data.findAll({ it.iD == 'c554b8ce-c873-4fef-b306-ec65d2f40394' || it.iD == '8d8f8a61-02d6-4d3e-9912-9ebb5d213c15'}) data.join(' ') " } } 
} 

只是表明ElasticSearch確實是多麼強大。

1

我不能幫助你與字段連接(也許它可能與腳本,但我沒有足夠的經驗,我會假設一個新的領域將不得不被生成等),但如何只檢索部分數據。

它至少需要ES 1.5,因爲它使用inner_hits並且您需要更改映射。

我加入typeinclude_in_parentdata類型:

DELETE somedata 
PUT somedata 
PUT somedata/sometype/_mapping 
{ 
    "sometype":{ 
     "dynamic_templates":[ 
     { 
      "defaultIDs":{ 
       "match_pattern":"regex", 
       "mapping":{ 
        "index":"not_analyzed", 
        "type":"string" 
       }, 
       "match":".*(id|ID|iD)" 
      } 
     } 
     ], 
     "properties":{ 
     "otherID":{ 
      "index":"not_analyzed", 
      "type":"string" 
     }, 
     "data":{ 
      "type": "nested", 
      "include_in_parent": true, 
      "properties":{ 
       "data":{ 
        "type":"string" 
       }, 
       "iD":{ 
        "index":"not_analyzed", 
        "type":"string" 
       } 
      } 
     }, 
     "iD":{ 
      "index":"not_analyzed", 
      "type":"string" 
     } 
     } 
    } 
} 

現在索引文檔:

PUT somedata/sometype/1 
{ 
     "otherID":"b4c95332-daed-49ae-99fe-c32482696d1c", 
     "data":[ 
     { 
      "data":"d2454d41-a74e-43af-b3b0-0febeaf67a99", 
      "iD":"9362f2eb-9bd7-4924-8b0e-77c27bb0aa56" 
     }, 
     { 
      "data":"some text", 
      "iD":"c554b8ce-c873-4fef-b306-ec65d2f40394" 
     }, 
     { 
      "data":"5256983c-ef69-4363-9787-97074297c646", 
      "iD":"8c90e2be-6042-4450-b0fd-0732900f8f65" 
     }, 
     { 
      "data":"other text", 
      "iD":"8d8f8a61-02d6-4d3e-9912-9ebb5d213c15" 
     }, 
     { 
      "data":"3", 
      "iD":"c880bfdf-eb4b-4c80-9871-fd44e06b2ed2" 
     } 
     ], 
     "iD":"31d3255d-67b4-40e6-b9d4-637383eb72ad" 
    } 

這裏是你如何能匹配,並與inner_hits檢索:

POST somedata/sometype/_search 
{ 
    "query": { 
    "nested": { 
     "path": "data", 
     "query": { 
     "bool": { 
      "should": [ 
      { 
      "term": { 
       "data.iD": "c554b8ce-c873-4fef-b306-ec65d2f40394" 
      } 
      }, 
      { 
      "term": { 
       "data.iD": "8d8f8a61-02d6-4d3e-9912-9ebb5d213c15" 
      } 
      } 
      ] 
     } 
     }, 
     "inner_hits": {} 
    } 
    } 
} 

結果現在看看這個路徑hits.hits[0].inner_hits.data.hits.hits[0]._source.data;它只包含你的兩個要求的比賽:現在

{ 
    "took": 1, 
    "timed_out": false, 
    "_shards": { 
     "total": 1, 
     "successful": 1, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 1, 
     "max_score": 0.5986179, 
     "hits": [ 
     { 
      "_index": "somedata", 
      "_type": "sometype", 
      "_id": "1", 
      "_score": 0.5986179, 
      "_source": { 
       "otherID": "b4c95332-daed-49ae-99fe-c32482696d1c", 
       "data": [ 
        { 
        "data": "d2454d41-a74e-43af-b3b0-0febeaf67a99", 
        "iD": "9362f2eb-9bd7-4924-8b0e-77c27bb0aa56" 
        }, 
        { 
        "data": "some text", 
        "iD": "c554b8ce-c873-4fef-b306-ec65d2f40394" 
        }, 
        { 
        "data": "5256983c-ef69-4363-9787-97074297c646", 
        "iD": "8c90e2be-6042-4450-b0fd-0732900f8f65" 
        }, 
        { 
        "data": "other text", 
        "iD": "8d8f8a61-02d6-4d3e-9912-9ebb5d213c15" 
        }, 
        { 
        "data": "3", 
        "iD": "c880bfdf-eb4b-4c80-9871-fd44e06b2ed2" 
        } 
       ], 
       "iD": "31d3255d-67b4-40e6-b9d4-637383eb72ad" 
      }, 
      "inner_hits": { 
       "data": { 
        "hits": { 
        "total": 2, 
        "max_score": 0.5986179, 
        "hits": [ 
         { 
          "_index": "somedata", 
          "_type": "sometype", 
          "_id": "1", 
          "_nested": { 
           "field": "data", 
           "offset": 3 
          }, 
          "_score": 0.5986179, 
          "_source": { 
           "data": "other text", 
           "iD": "8d8f8a61-02d6-4d3e-9912-9ebb5d213c15" 
          } 
         }, 
         { 
          "_index": "somedata", 
          "_type": "sometype", 
          "_id": "1", 
          "_nested": { 
           "field": "data", 
           "offset": 1 
          }, 
          "_score": 0.5986179, 
          "_source": { 
           "data": "some text", 
           "iD": "c554b8ce-c873-4fef-b306-ec65d2f40394" 
          } 
         } 
        ] 
        } 
       } 
      } 
     } 
     ] 
    } 
} 

inner_hits是相當新的文件還指出:

警告:此功能是實驗性的,並在未來的版本可以改變或徹底刪除。

YMMV。

另一件要注意的事情:inner_hits按分數排序。在你的原始文件中,它們是在的數組中,但實際結果中丟失了這些信息。如果您需要在inner_hits中以相同的順序使用它們,我認爲您需要添加一個單獨的字段進行排序(可能只是數組索引...)並按其排序inner_hits

+0

感謝您花時間回覆@mark。你當然指出了我的正確方向。看到這個警告雖然有點令人沮喪。而且,如果甚至可能,連接會變得如此複雜,以至於不值得。*嘆息*如果在接下來的幾個小時內沒有其他令人意外的答案出現,我會接受你的。再次感謝:-) –

+1

如果不知道數據結構的完整意圖,可能將它以不同的方式存儲到ES中,針對您的情況進行優化即可。主要將data []'數組索引爲type,並將'iD'和'orderID'附加到它,並且不帶'inner_hits'的查詢(仍然不解決排序和連接)。 – mark

+0

謝謝@mark。我意識到我的數據結構需要改變的原因很多。不過,我仍然需要這種連接能力,事實證明有很多方法可以實現這一點。如果您有興趣知道,我已在此發佈答案。 –