I'm indexing a set of documents (imagine them as forum posts) with a nested object which is the user related to that post. My problem is that the user fields might be updated, but since the posts do not change they are not reindexed and the user nested objects become outdated. Is there a way to update the nested objects without reindexing the whole document again? Or the only solution would be to reindex all the related posts of a user everytime that the user changes?
The script can update, delete, or skip modifying the document. The update API also supports passing a partial document, which is merged into the existing document. To fully replace an existing document, use the index API.
Nested queryedit. Wraps another query to search nested fields. The nested query searches nested field objects as if they were indexed as separate documents. If an object matches the search, the nested query returns the root parent document.
In Elasticsearch, to replace a document you simply have to index a document with the same ID and it will be replaced automatically. If you would like to update a document you can either do a scripted update, a partial update or both.
You can use the Update API.
curl -XPOST localhost:9200/docs/posts/post/_update -d '{ "script" : "ctx._source.nested_user = updated_nested_user", "params" : { "updated_nested_user" : {"field": "updated"} } }'
See this SO answer for full detail.
Note that update scripts support conditional logic, as shown here. So you could tag forum posts when the user changes, then iterate over the posts to update only posts with changed users.
curl -XPOST 'localhost:9200/docs/posts/post/_update' -d '{ "script" : "ctx._source.tags.contains(tag) ? "ctx._source.nested_user = updated_nested_John" : ctx.op = "none"", "params" : { "tag": "updated_John_tag", "updated_nested_John" : {"field": "updated"} } }'
UPDATED
Perhaps my ternary operator example was incomplete. This was not mentioned in the question, but assuming that users change their info in a separate part of the app, it would be nice to apply those changes to the forum posts in one script. Instead of using tags, try checking the user field directly for changes:
curl -XPOST 'localhost:9200/docs/posts/post/_update' -d '{ "script" : "ctx._source.nested_user.contains(user) ? "ctx._source.nested_user = updated_nested_John" : ctx.op = "none"", "params" : { "user": "John", "updated_nested_John" : {"field": "updated"} } }'
As mentioned, though, this may be a slower operation than reindexing the full posts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With