2012-11-25 57 views
4

我們在彈性搜索(ES)上使用兩種類型的文檔:項目和插槽,其中項目是插槽文檔的父項。 我們定義使用以下命令索引:彈性搜索與父子文檔的問題

curl -XPOST 'localhost:9200/items' -d @itemsdef.json 

其中itemsdef.json具有以下定義

{ 
"mappings" : { 
    "item" : { 
     "properties" : { 
      "id" : {"type" : "long" }, 
      "name" : { 
       "type" : "string", 
       "_analyzer" : "textIndexAnalyzer" 
      }, 
      "location" : {"type" : "geo_point" }, 
     } 
    } 
}, 
"settings" : { 
    "analysis" : { 
     "analyzer" : { 

       "activityIndexAnalyzer" : { 
        "alias" : ["activityQueryAnalyzer"], 
        "type" : "custom", 
        "tokenizer" : "whitespace", 
        "filter" : ["trim", "lowercase", "asciifolding", "spanish_stop", "spanish_synonym"] 
       }, 
       "textIndexAnalyzer" : { 
        "type" : "custom", 
        "tokenizer" : "whitespace", 
        "filter" : ["word_delimiter_impl", "trim", "lowercase", "asciifolding", "spanish_stop", "spanish_synonym"] 
       }, 
       "textQueryAnalyzer" : { 
        "type" : "custom", 
        "tokenizer" : "whitespace", 
        "filter" : ["trim", "lowercase", "asciifolding", "spanish_stop"] 
       }  
     }, 
     "filter" : {   
       "spanish_stop" : { 
        "type" : "stop", 
        "ignore_case" : true, 
        "enable_position_increments" : true, 
        "stopwords_path" : "analysis/spanish-stopwords.txt" 
       }, 
       "spanish_synonym" : { 
        "type" : "synonym", 
        "synonyms_path" : "analysis/spanish-synonyms.txt" 
       }, 
       "word_delimiter_impl" : { 
        "type" : "word_delimiter", 
        "generate_word_parts" : true, 
        "generate_number_parts" : true, 
        "catenate_words" : true, 
        "catenate_numbers" : true, 
        "split_on_case_change" : false     
       }    
     } 
    } 
} 
} 

然後我們使用以下命令添加子文檔定義:

curl -XPOST 'localhost:9200/items/slot/_mapping' -d @slotsdef.json 

在哪裏slotsdef.json定義如下:

{ 
"slot" : { 
    "_parent" : {"type" : "item"}, 
    "_routing" : { 
     "required" : true, 
     "path" : "parent_id" 
    }, 
    "properties": { 
     "id" : { "type" : "long" }, 
     "parent_id" : { "type" : "long" }, 
     "activity" : { 
      "type" : "string", 
      "_analyzer" : "activityIndexAnalyzer" 
     }, 
     "day" : { "type" : "integer" }, 
     "start" : { "type" : "integer" }, 
     "end" : { "type" : "integer" } 
    } 
} 
} 

最後,我們用下面的命令執行批量指數:

curl -XPOST 'localhost:9200/items/_bulk' --data-binary @testbulk.json 

凡testbulk.json持有以下數據:

{"index":{"_type": "item", "_id":35}} 
{"location":[40.4,-3.6],"id":35,"name":"A Name"} 
{"index":{"_type":"slot","_id":126,"_parent":35}} 
{"id":126,"start":1330,"day":1,"end":1730,"activity":"An Activity","parent_id":35} 

我們通過ES頭插件看到的定義似乎是好。我們測試分析儀以檢查它們是否已經加載並且工作。這兩個文檔都顯示在ES Head瀏覽器視圖中。但是,如果我們嘗試使用API​​來檢索子項,ES響應它不存在:

$ curl -XGET 'localhost:9200/items/slot/126' 
{"_index":"items","_type":"slot","_id":"126","exists":false} 

當我們導入50個文檔,所有的父文件可以通過API檢索,但只有一些對請求子元素得到了成功的迴應。

我的猜測是,它可能與文檔如何存儲在分片和路由之間......這當然不清楚它是如何工作的。

關於如何檢索單個子文檔的任何線索? ES頭顯示它們已被存儲,但HTTP GETs到localhost:9200/items/slot/XXX隨機響應「exists」:false。

回答

10

子文檔正在使用父母的ID進行路由。因此,爲了檢索子文檔,您需要在路由參數指定您的查詢父ID:

curl "localhost:9200/items/slot/126?routing=35" 

如果父ID不可,你將不得不尋找孩子的文檔:

curl "localhost:9200/items/slot/_search?q=id:126" 

或切換到具有單個分片的索引。

+0

不,我認爲'items'指的是索引的名稱。 'item'是我認爲的實際父類型。 – Atharva

+0

你絕對沒錯,@Athara。謝謝! – imotov

+0

嗨@imotov&Atharva,感謝您的及時回覆。兩種解決方案都可以工我想延長這個問題......因爲我完全無法做出簡單的has_child查詢。我將重新編輯問題以添加此片段。 –