在嵌套对象更改时更新多个文档

Updating multiple documents on nested object change

我在 Rails 应用上为我的 Ruby 使用 elasticsearch-railselasticsearch-model gem,它就像一个问答网站。

我的主要问题是:当嵌套在多个文档中的嵌套对象发生更改时,您如何告诉 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 调用什么来确保它更新所有相应的 questions 使用新的用户名。有人知道吗?它甚至可以帮助我了解 RESTful/curl 请求应该是什么样子?

如有任何帮助,我们将不胜感激!

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

您可以阅读有关各种选项的信息 here. If you can set things up as a one-to-many relationship, then the parent/child relationship 可能是正确的选择。然后你可以这样设置:

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

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

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

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

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

这是我用来处理最后一点的一些代码:

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