2017-05-08 84 views
0

我在搜索大孩子時面臨彈性搜索的一些奇怪行爲。我的大孩子並不認可每個父母文件。當我要求彈性搜索返回父母的孩子時,它會返回所有可能的匹配。然後,當我要求將那些擁有大孩子的孩子還給我時,我就會得到不正確的結果。有一段時間我沒有得到點擊或更少。但是,當我檢查我的大孩子的路由和父母身份時,我發現他們確實存在於他們的父母身上。但我不明白爲什麼我會得到不正確的結果。你們有沒有遇到過這種類型的問題? 。 我三次檢查了我的代碼,並沒有發現任何類型的錯誤:-( 讓我告訴你重現此錯誤的步驟ElasticSearch:孫子/孩子/父母關係不正常

這裏是我的映射:

PUT /的test_index

{ 
    "mappings":{ 
     "parentDoc":{ 
      "properties":{ 
       "id":{ 
        "type":"integer" 
       }, 
       "name":{ 
        "type":"text" 
        } 
       } 
     }, 
     "childDoc": { 
      "_parent": { 
       "type": "parentDoc" 
      }, 
      "properties":{ 
       "id":{ 
        "type":"integer" 
       }, 
       "name":{ 
        "type":"text" 
       }, 
       "contact": { 
        "type":"text" 
       } 
      } 
     }, 
     "grandChildDoc": { 
      "_parent": { 
       "type": "childDoc" 
      }, 
      "properties":{ 
       "id":{ 
        "type":"integer" 
       }, 
       "description":{ 
        "type":"text" 
       } 
      } 
     } 
    } 
} 

索引parentDoc:

PUT /的test_index/parentDoc/1

{ 
    "pdId":1, 
    "name": "First parentDoc" 
} 

PUT /的test_index/parentDoc/2

{ 
    "pdId":2, 
    "name": "Second parentDoc" 
} 

索引childDoc:

PUT /的test_index/childDoc/10? parent = 1

PUT /的test_index/childDoc/101父= 1

{ 
    "cdId":101, 
    "name": "Second childDoc", 
    "contact" : "+XX0000000111" 
} 

PUT /的test_index/childDoc/20母體= 2

{ 
    "cdId":20, 
    "name": "Third childDoc", 
    "contact" : "+XX0011100000" 
} 

索引grandChildDoc:

PUT/test_index/grandChildDoc/100→父= 10

{ 
    "gcdId":100, 
    "name": "First grandChildDoc" 
} 

PUT /的test_index/grandChildDoc/200?父= 10

{ 
    "gcdId":200, 
    "name": "Second grandChildDoc" 
} 

PUT /的test_index/grandChildDoc/300?父= 20

{ 
    "gcdId":300, 
    "name": "Third grandChildDoc" 
} 

現在,當我問彈性搜索給我看那些parentDoc具有childDoc,則返回: POST /的test_index/parentDoc/_search

{ 
    "query": { 
     "has_child": { 
      "type": "childDoc", 
      "query": { 
       "match_all": {} 
      } 
     } 
    } 
} 

結果:(看起來很好。)

{ 
    "took": 3, 
    "timed_out": false, 
    "_shards": { 
     "total": 5, 
     "successful": 5, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 2, 
     "max_score": 1, 
     "hits": [ 
      { 
       "_index": "test_index", 
       "_type": "parentDoc", 
       "_id": "2", 
       "_score": 1, 
       "_source": { 
        "pdId": 2, 
        "name": "Second parentDoc" 
       } 
      }, 
      { 
       "_index": "test_index", 
       "_type": "parentDoc", 
       "_id": "1", 
       "_score": 1, 
       "_source": { 
        "pdId": 1, 
        "name": "First parentDoc" 
       } 
      } 
     ] 
    } 
} 

現在,當我問elasticsearch給我看那些childDoc具有grandChildDoc,則返回: POST /的test_index/childDoc/_search

{ 
    "query": { 
     "has_child": { 
      "type": "grandChildDoc", 
      "query": { 
       "match_all": {} 
      } 
     } 
    } 
} 

結果:(在這裏,你會注意到一些命中失蹤。例如childDoc與編號和缺失)。

{ 
    "took": 7, 
    "timed_out": false, 
    "_shards": { 
     "total": 5, 
     "successful": 5, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 1, 
     "max_score": 1, 
     "hits": [ 
      { 
       "_index": "test_index", 
       "_type": "childDoc", 
       "_id": "20", 
       "_score": 1, 
       "_routing": "2", 
       "_parent": "2", 
       "_source": { 
        "cdId": 20, 
        "name": "Third childDoc", 
        "contact": "+XX0011100000" 
       } 
      } 
     ] 
    } 
} 

任何想法我在做什麼錯誤?或者它是一個bug?任何解決方法或解決方案?

[注意:我使用elasticsearch V5.4]

回答

0

我有相同的工作。我正在使用logstash以彈性索引文檔。

根本原因:

我已經探討的根本原因。默認情況下,彈性分配5個分片和一組父子孫的文檔必須位於相同的分片中。不幸的是,數據遍佈在碎片上。 Elastic將只返回那些在同一個分片中的記錄。

解決方案:

親子-孫子的工作,你需要有盛大父文檔ID作爲盛大子文檔路由值。

對於單級(父子),父值是deafult路由值,它工作正常。但是對於三個級別,您需要爲盛大兒童中的每個文檔配置路由。

正如我所提到的,路由值應該是盛大的父母id。

請看以下例子使用logstash:

  1. 家長

    "index" => "search" 
    "document_type" => "parent" 
    "document_id" => "%{appId}" 
    
  2. 兒童:缺省的工作,因爲父母/路由是相同的父文件ID。路由公式(shard_num =散列(_routing)%num_primary_shards)

    "index" => "search" 
    "document_type" => "child" 
    "document_id" => "%{lId}" 
    "parent" => "%{appId}" 
    
  3. 孫:注意路由是APPID這是盛大父文檔ID

    "index" => "search" 
    "document_type" => "grandchild" 
    "document_id" => "%{lBId}" 
    "parent" => "%{lId}" 
    "routing" => "%{appId}" 
    

這將索引中的所有文件相同碎片和搜索在這個用例中正常工作。