更新嵌套对象上的多个文档

时间:2015-10-30 06:31:49

标签: ruby-on-rails ruby-on-rails-3 elasticsearch

我在我的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

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

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

有几种不同的方法可以解决这个问题。但是,它们可能都需要进行一些代码更改。我不认为有一种方法可以直接用您当前的设置做出要求。

您可以阅读各种选项here。如果您可以将事物设置为一对多关系,那么parent/child relationship可能就是您的选择。然后你可以设置这样的东西:

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

在这种情况下,您可以独立于users更新questions。但它使查询更加复杂,这可能是您的应用程序代码中的问题,也可能不是。

鉴于您已经设置了嵌套文档,您可以简单地查询将该特定用户作为嵌套文档的所有文档,例如:

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

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

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

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