2011-12-20 11 views
1

モンゴイドを使ってジオのハッシュ順序を保証する方法はありますか?モンゴイドを使ってジオのハッシュ順序を保証する方法はありますか?

現在、私はそれをこのように保存し、順序を保証するために、コールバックでいくつかの魔法を実行します。

field :location, type: Hash // { :lng => 33.33, :lat => 45 } 

set_callback(:save, :before) do |doc| 
    if doc.location_changed? 
     doc.location = {lng: doc.location[:lng], lat: doc.location[:lat]} 
    end 
end 

はクラスとして、このハッシュを宣言するためのいくつかの方法があるかもしれませ。私はEmbeded Documentについて考えましたが、それは_idです。

+0

注:ここではhttps://github.com/ricodigo/shapado/blob/master/app/models/geo_position.rb

は配列としてMongoDBの中で場所を格納し、私自身の実装です緯度と経度を含むフィールドのサブ文書(「ハッシュ」)ではなく配列を使用する必要があります。http://www.mongodb.org/display/DOCS/Geospatial+Indexing(最初の注釈を参照) – dcrosta

+0

私はこれについて知っています。よりエレガントな方法を探してみてください。 –

答えて

1

このためmongoid custom field serializationを使用することが可能です。ここで

が良い例です:あなたは、地理空間インデックスは、常にすべてのドライバで正常に動作することを確認するために

class LatLng 
    include Mongoid::Fields::Serializable 

    attr_reader :lat, :lng 

    def serialize(value) 
    return if value.nil? 

    if value.is_a?(self.class) 
     [value.lng.to_f, value.lat.to_f] 
    elsif value.is_a?(::Hash) 
     hash = value.with_indifferent_access 
     [hash['lng'].to_f, hash['lat'].to_f] 
    end 
    end 

    def deserialize(value) 
    return if value.nil? 

    value.is_a?(self.class) ? value : LatLng.new(value[1], value[0]) 
    end 

    def initialize(lat, lng) 
    @lat, @lng = lat.to_f, lng.to_f 
    end 

    def [](arg) 
    case arg 
     when "lat" 
     @lat 
     when "lng" 
     @lng 
    end 
    end 

    def to_a 
    [lng, lat] 
    end 

    def ==(other) 
    other.is_a?(self.class) && other.lat == lat && other.lng == lng 
    end 
end 
0

使用BSON::OrderedHash

BSON::OrderedHash[:lng => 33.33, :lat => 45] 
+0

ruby​​で1.9のハッシュはすでに順序付けされています - BSON :: OrderedHashはハッシュの別名です –

+0

ありがとうございました。私は別の解決策を見つけました。それがあなたにも役立つことを願っています。 –

関連する問題