2012-04-13 4 views
1

tun (Rubin 1.9.3, MongoDB 2.0.4, Rails 3.2, 2.4 Mongoid, Geocoder 1.1.1)Kann nicht geo Abfrage auf Embedded-Dokument mit Mongoid und Geocoder

Ich habe folgende Modelle:

class Company 
    include Mongoid::Document 

    embeds_one :office 

    index [[ "office.coordinates", Mongo::GEO2D ]] 
end 

class Office 
    include Mongoid::Document 
    include Geocoder::Model::Mongoid 

    geocoded_by :address 

    field :city,  :type => String 
    field :state,  :type => String 
    field :coordinates, :type => Array 

    embedded_in :company 

    after_validation :geocode 

    def address 
    "#{city}, #{state}" 
    end 
end 

ich tue dies in der Konsole:

> c = Company.new 
=> #<Company _id: 4f885aa56d20f03898000003, _type: nil> 
> c.office = Office.new(:city => "San Francisco", :state => "CA") 
=> #<Office _id: 4f885ab66d20f03898000004, _type: nil, city: "San Francisco", state: "CA", coordinates: nil> 
> c.save 
=> true 

so weit so gut. Aber dann versuche ich die Firma abzurufen, indem ein geoquery auf seine eingebettete Dokument (Büro) zu tun:

> Company.where(:office.near => Company.first.office.to_coordinates).first 
Mongo::OperationFailure: can't find special index: 2d for: { office: { $near: [ -122.4194155, 37.7749295 ] } } 
    from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongo-1.6.2/lib/mongo/cursor.rb:144:in `next' 
    from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongo-1.6.2/lib/mongo/collection.rb:288:in `find_one' 
    from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongoid-2.4.8/lib/mongoid/collections/master.rb:25:in `block in find_one' 
    from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongoid-2.4.8/lib/mongoid/collections/retry.rb:29:in `retry_on_connection_failure' 
    from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongoid-2.4.8/lib/mongoid/collections/master.rb:24:in `find_one' 
    from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongoid-2.4.8/lib/mongoid/collection.rb:60:in `find_one' 
    from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongoid-2.4.8/lib/mongoid/contexts/mongo.rb:203:in `first' 
    from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongoid-2.4.8/lib/mongoid/criteria.rb:45:in `first' 
    from (irb):2 
    from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.3/lib/rails/commands/console.rb:47:in `start' 
    from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.3/lib/rails/commands/console.rb:8:in `start' 
    from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.3/lib/rails/commands.rb:41:in `<top (required)>' 
    from script/rails:6:in `require' 
    from script/rails:6:in `<main>' 

Was mache ich falsch? Ich habe rake db:mongoid:create_indexes ausgeführt.

Antwort

6

Sie müssen die Abfrage für die Embedded-Bereich auszuführen:

Company.where(:'office.coordinates'.near => Company.first.office.to_coordinates).first 

Wenn Sie den near Umfang durch den Geocoder Juwel geschaffen nutzen möchten unter Office, können Sie so etwas wie das folgende tun:

# in Company.rb 
self.near(office, radius = 20, conditions = {}) 
    self.where(conditions).tap do |criteria| 
    near_criteria = Office.scopes[:near].conditions.call(office, radius) 

    criteria.selector[:'office.coordinates'] = near_criteria.selector[:coordinates] 
    end 
end 

Dies erstellt Company#near, die ein Objekt Office dauert. Es wird die vom Bereich Office#near erstellte Abfrage in eine Abfrage für ein Unternehmen einfügen.

+0

Sie wollten den Geocoder aktualisieren, um auf eingebettete Modelle für Mongoide zu achten. Leichter gesagt als getan: D – mikeycgto