Chance
Chance

Reputation: 11285

Geospatial searches with Solr (websolr) in Rails 3.x

I am looking to utilize Solr for both text and geospatial searching in a Rails 3.1 app. I see that websolr supports geo-spatial indexing & searches but the two gems for it (sunspot & rsolr) do not seem to (currently) implement it. Sunspot appears to be in the process of adding the functionality but claims that "[geospatial is] experimental and unreleased. The DSL may change."

Are there other implementations of geospatial searching with sunspot + websolr? I've done a bit of googing and come across some but they seem hackish and I'd rather not use what I've found if there is already a core feature being baked in or a more supported approach.

Upvotes: 1

Views: 1900

Answers (2)

Nick Zadrozny
Nick Zadrozny

Reputation: 7944

For posterity: Sunspot has since released version 1.3.0 with support for Solr 3 spatial search, making it a perfectly viable option on Heroku with Websolr.

Upvotes: 2

Robin
Robin

Reputation: 21884

Sunspot does support geo-spatial search, with some limitations.

Indexing:

searchable do
  text :location
  location :coordinates do
    Sunspot::Util::Coordinates.new latitude, longitude
  end
end

Search:

coord = # whatever...
with(:coordinates).near(coord[0], coord[1], :precision => 3)

But it's really not precise... It's using geo hashes if I'm not mistaken. So it's possible that 2 points are close from each other but are not found.
Also, you can't nest near in facets.

I would follow the advice of ADAM and go for elastic search. That's what I did. You get a lot more control.

Tire also supports geospatial search, but there is no specific methods in the DSL, because it's not needed. They plan to add them later I think.

Indexing:

tire.mapping do
    indexes :location, type: 'string', analyzer: 'snowball'
    indexes :latitude_longitude, type: 'geo_point'
end

def latitude_longitude
    [latitude, longitude].join(",")
end

def to_indexed_json
    to_json(methods: ['latitude_longitude'])
end

Search:

filter :geo_distance, distance: "#{distance}km", latitude_longitude: [user.latitude, user.longitude].join(",")

Upvotes: 7

Related Questions