0

I am using the elasticsearch-rails and elasticsearch-model gems for my Ruby on Rails app, which is like a question-and-answer site.

My main question is: how do you tell Elasticsearch which documents to update when there was a change to a nested object that's nested in multiple documents?

I have one index my_index and mappings for question, and answer. In particular, question has a nested object with a user:

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

It's possible for a user to change his name, and I have hooks to update the user in Elasticsearch:

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

But this isn't updating the appropriate question objects correctly, and I don't know what to pass to the index_document call to make sure it updates all the corresponding questions with the new user name. Does anyone know? It might even help me to see what a RESTful/curl request should look like?

Any help would be appreciated!

boo-urns
  • 10,136
  • 26
  • 71
  • 107

1 Answers1

0

There are a couple of different ways you can go about this. They are all probably going to require some code changes, though. I don't think there is a way to do what you are asking directly, with your current setup.

You can read about the various options here. If you can set things up as a one-to-many relationship, then the parent/child relationship is probably the way to go. Then you could set up something like this:

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

And in that case you would be able to update users independently of questions. But it makes querying more complicated, which may or may not be a problem in your application code.

Given that you already have nested documents set up, you could simply query for all the documents that have that particular user as a nested document, with something like:

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

and once you have all the affected question documents you can modify the user name in each one and update all the documents with a bulk index request.

Here is some code I used to play around with that last bit:

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

Community
  • 1
  • 1
Sloan Ahrens
  • 8,588
  • 2
  • 29
  • 31
  • Hey, Sloan, so this does make querying more difficult. In particular, I'm trying to set up grandparents and grandchildren (like https://www.elastic.co/guide/en/elasticsearch/guide/current/grandparents.html), but it seems that `inner_hits` stops working... Do you have any ideas as to why that might be happening? – boo-urns Nov 04 '15 at 21:45