1

So I am running a Rails 5 application using elasticsearch-rails Gem to work with Elasticsearch 5.4.

Everything works fine, the only problem I am having is that when I update the location using Geocoding to retrieve the new longitude and latitude, the coordinates do not get updated in Elasticsearch (using Geopoint). It is however correctly reflected in the database, meaning Geocoding, etc. works fine.

models/concerns/user_searchable.rb

include Elasticsearch::Model
include Elasticsearch::Model::Callbacks

index_name Rails.application.class.parent_name.underscore
document_type self.name.downcase

settings index: { number_of_shards: 1 } do
  mapping dynamic: false do
    indexes :description, analyzer: 'english'
    indexes :tagline, analyzer: 'english'
    indexes :username
    indexes :location, type: 'geo_point'
    indexes :active, type: 'boolean'
    ...
  end
end

after_touch() { __elasticsearch__.index_document }

def as_indexed_json(_options = {})
  self.as_json(
      except: [:email, :lat, :lng, :status, :termsofuse, :v_code],
      include: {
          photos: { only: [:name, :caption, :active, :image_data] }
  ).merge(
      location: {lat: lat, lon: lng},
      age: birthday.nil? ? 18 : ((Date.today - birthday.to_date) / 365.25).floor
  )
end

Perhaps someone has a quick fix for this.

Georg Keferböck
  • 1,967
  • 26
  • 43
  • Could you check `as_indexed_json` on some object to check if there is location at all ? Maybe the issue is you're not sending location to ES on updating – zauzaj Jun 20 '17 at 11:31
  • One more thing, are you sure when you update location it's saved/updated on object too ? – zauzaj Jun 20 '17 at 11:33
  • Hi Zauzaj, yes there is a location ( I can query it, see it in Kibana, etc.). Not sure what you mean by upload location. I update geocode lat und lon in code which is sent to DB. elasticsearch-rails updates all attributes (except location). If I remove lat, lng from the except clause in self.as_json the float/decimal values do get updated correctly. But again, Geo_point does not get updated. That makes me believe there is a bug, unless there is something that needs to be done that I don't know and I can't find on google or the documentation :( – Georg Keferböck Jun 20 '17 at 11:39
  • I'm not 100% sure but I'm guessing that merge inside `as_indexed_json` makes some mess there. Can you make a instance method `location` which will return {lat: lat, lon: lng} and then you can just include such method inside `as_indexed_json` ? – zauzaj Jun 20 '17 at 11:52
  • Great idea! You might be onto something here. Will test this in the evening and post the results here. :) – Georg Keferböck Jun 20 '17 at 11:54
  • Sorry for the late response, but it has been a busy few weeks. zauzaj you are correct, creating an instance method that returns lat and long resolves the issue. Please feel free to add an answer so I can give you the points for your assistance. – Georg Keferböck Jul 06 '17 at 14:41

2 Answers2

1

As I am working on a low traffic application I use a simple work-around:

As Geo_points are being set on create, but not on update, I simply delete the document and reindex it whenever lat or long is being touched.

user.__elasticsearch__.delete_document
user.__elasticsearch__.index_document

If anyone knows a better solution, please post. I also logged an issue with elasticsearch-rails.

Georg Keferböck
  • 1,967
  • 26
  • 43
1

@Georg Keferböck

You make a instance method location which will return { lat: lat, lon: lng } and then you can just include such method inside as_indexed_json. That way it will be much more cleaner and also you can reuse it afterwards ;)

Regards

zauzaj
  • 1,206
  • 12
  • 20
  • This will work because of your `after_touch() { __elasticsearch__.index_document }` but anyone else should be aware that computed/derived attributes will not get updated automatically due to this bug: https://github.com/elastic/elasticsearch-rails/pull/182 – Meekohi Jul 17 '17 at 18:51