2015-04-17 121 views
1

我是ElasticSearch的新手。我在.NET項目中使用它,並使用NEST客戶端。現在我正在研究處理文檔更新的方法。更新ElasticSearch文檔中列表中對象的屬性?

我有一個文件,看起來像這樣:

public class Class1 
{ 
    public string Prop1 { get; set; } 
    public string Prop2 { get; set; } 
    public List<Class2> PropList { get; set; } 
} 

,當我想補充一點的proplist這樣,我被劇本做:

client.Update<Class1>(x => x 
      .Id(1) 
      .Index("index_name") 
      .Script("ctx._source.propList += prop") 
      .Params(p => p.Add("prop", newProp))); 

完美的作品的權利現在。問題是當我想更新propList中的對象的屬性。我現在正在做的方式是檢索整個文檔,在列表中找到對象,更新屬性並重新索引整個文檔,這在某些時候會導致性能問題。

有沒有辦法更有效地做到這一點?也許使用腳本或其他方式?

謝謝。

回答

1

我不知道如何設置它與鳥巢,副手,但我會去parent/child relationship

作爲一個玩具的例子,我建立了一個指標與此映射:

PUT /test_index 
{ 
    "mappings": { 
     "parent_type": { 
     "properties": { 
      "num_prop": { 
       "type": "integer" 
      }, 
      "str_prop": { 
       "type": "string" 
      } 
     } 
     }, 
     "child_type": { 
     "_parent": { 
      "type": "parent_type" 
     }, 
     "properties": { 
      "child_num": { 
       "type": "integer" 
      }, 
      "child_str": { 
       "type": "string" 
      } 
     } 
     } 
    } 
} 

然後增加了一些數據:

POST /test_index/_bulk 
{"index":{"_type":"parent_type","_id":1}} 
{"num_prop":1,"str_prop":"hello"} 
{"index":{"_type":"child_type","_id":1,"_parent":1}} 
{"child_num":11,"child_str":"foo"} 
{"index":{"_type":"child_type","_id":2,"_parent":1}} 
{"child_num":12,"child_str":"bar"} 
{"index":{"_type":"parent_type","_id":2}} 
{"num_prop":2,"str_prop":"goodbye"} 
{"index":{"_type":"child_type","_id":3,"_parent":2}} 
{"child_num":21,"child_str":"baz"} 

現在,如果我想更新子文檔我可以只交新版本:

POST /test_index/child_type/2?parent=1 
{ 
    "child_num": 13, 
    "child_str": "bars" 
} 

(請注意,我必須提供父ID,以便ES能route the request appropr iately)

我還可以做的部分,腳本更新,如果我想:

POST /test_index/child_type/3/_update?parent=2 
{ 
    "script": "ctx._source.child_num+=1" 
} 

我們可以證明這種通過搜索子類型的工作:

POST /test_index/child_type/_search 
... 
{ 
    "took": 2, 
    "timed_out": false, 
    "_shards": { 
     "total": 5, 
     "successful": 5, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 3, 
     "max_score": 1, 
     "hits": [ 
     { 
      "_index": "test_index", 
      "_type": "child_type", 
      "_id": "1", 
      "_score": 1, 
      "_source": { 
       "child_num": 11, 
       "child_str": "foo" 
      } 
     }, 
     { 
      "_index": "test_index", 
      "_type": "child_type", 
      "_id": "2", 
      "_score": 1, 
      "_source": { 
       "child_num": 13, 
       "child_str": "bars" 
      } 
     }, 
     { 
      "_index": "test_index", 
      "_type": "child_type", 
      "_id": "3", 
      "_score": 1, 
      "_source": { 
       "child_num": 22, 
       "child_str": "baz" 
      } 
     } 
     ] 
    } 
} 

希望這有助於。這裏是我使用的代碼,再加上幾個例子:

http://sense.qbox.io/gist/73f6d2f347a08bfe0c254a977a4a05a68d2f3a8d

+0

對不起,遲到的迴應。我很感謝你的回答,這對我很有意義。但是,由於不同的原因(我們將在ES中構建數據的方式發生變化等),我決定採用不同的方法,那就是: 我從我的示例中殺掉了Class1,並且僅索引了Class2,因爲這兩個屬性從Class1開始沒有什麼意義(實際上,這兩個屬性都已經存在於Class2中了,所以)。 這樣做之後,針對索引中特定文檔的CRUD操作變得更簡單,更易於維護。 –