2015-10-30 98 views
0

我为我的Ruby on Rails应用程序使用elasticsearch-railselasticsearch-model宝石,这就像问答网站。在嵌套对象更新上更新多个文档

我的主要问题是:当嵌套在多个文档中的嵌套对象发生更改时,如何告知Elasticsearch要更新哪些文档?

我有一个索引my_index和映射questionanswer。特别是,question有一个user嵌套对象:

"question": { 
    "properties": { 
     "user": { 
     "type": "nested", 
     "properties": { 
      "created_at": { 
       "type": "date", 
       "format": "dateOptionalTime" 
      }, 
      "name": { 
       "type": "string" 
      }, 
      "id": { 
       "type": "long" 
      }, 
      "email": { 
       "type": "string" 
      } 
      } 
     } 
     ... 
    } 
} 

这有可能为用户更改他的名字,我有钩更新Elasticsearch用户:

after_commit lambda { __elasticsearch__.index_document}, on: :update 

但这ISN不正确地更新适当的question对象,我不知道要传递给index_document调用的内容,以确保它使用新的用户名更新所有相应的question。有人知道吗?它甚至可以帮助我看看RESTful/curl请求应该是什么样子?

任何帮助,将不胜感激!

回答

0

有几种不同的方法可以解决这个问题。不过,它们都可能需要更改代码。我不认为有一种方法可以根据您当前的设置直接询问您的问题。

您可以阅读关于各种选项here。如果你能把事情设置成一对多的关系,那么parent/child relationship可能就是要走的路。然后,你可以建立这样的事情:

PUT my_index 
{ 
    "mappings": { 
     "user": { 
     "properties": {...} 
     }, 
     "question": { 
     "_parent": { 
      "type": "user" 
     }, 
     "properties": {...} 
     } 
    } 
} 

而且在这种情况下,你就可以单独更新usersquestions。但它使查询更复杂,这可能会或可能不会成为您的应用程序代码中的问题。

既然你设置已经嵌套的文件,你可以简单地查询所有具有特定用户为嵌套文件的文件,喜欢的东西:

POST /test_index/question/_search 
{ 
    "filter": { 
     "nested": { 
     "path": "user", 
     "filter": { 
      "term": { 
       "user.id": 2 
      } 
     } 
     } 
    } 
} 

,一旦你拥有所有的影响question文档,您可以修改每个文档中的用户名,并使用bulk index请求更新所有文档。

下面是一些代码我用来玩的最后一点:

http://sense.qbox.io/gist/d2a319c6b4e7da0d5ff910b4118549228d90cba0

+0

嘿,斯隆,所以这确实让查询变得更加困难。特别是,我试图建立祖父母和孙子女(像https://www.elastic.co/guide/en/elasticsearch/guide/current/grandparents.html),但似乎'inner_hits'停止工作。 ..你有什么想法,为什么可能会发生? – user5243421