0

データと呼ばれるコレクションがあります。各ドキュメントは次のようになります。

x: {"value"=>1358747699.6922424}, y: {"value"=>17.9}

また、x.value と y.value にインデックスがあります。組み込みの mongoid 集計 .min を使用して、最小の y 値を取得したいと考えました。私はこれをやってみました:

data.min(:'y.value')

そして、それは16.2を返しますが、これは正しくないことがわかっています.14.4である必要があります。これは次の方法で証明できます。

data.map{|d| d['y']d['value']}.sort.first

14.4を返します

または:

data.order_by([:'y.value', :asc]).limit(1).first['y']['value']

14.4も返します

なぜ .min が正しく動作していないように見えるのかわかりませんか?

4

1 に答える 1

1

簡潔な答え

あなたの場合、minMongoid が提供する関数を無視してください。代わりに思いついたものを使用してください:

data.order_by([:'y.value', :asc]).limit(1).first['y']['value']

説明

Mongoid アグリゲーションが実際にどのように実装されているかを掘り下げました。map_reduceコレクション全体を実行するを使用していることがわかりました。[1]

作成したクエリは、作成したインデックスを使用できるため、はるかに効率的ですy.value。これは、コレクション全体に対して 1 つのインデックス ルックアップを意味します (実際に機能することは言うまでもありません...)。

MongoDB プロファイラーをチェックして、インデックスが実際に使用されていることを確認します。[2]

あなたが実際に尋ねた質問

失敗する正確な理由についてminは、私は途方に暮れています。あなたのデータを見なければ、基礎となるものが失敗する理由はわかりませmap_reduceん。埋め込みフィールドに関係があるthis.y.valueか、一部のオブジェクトで定義されていない可能性があります。

オープンソースに恩返しをするチャンスです。Mongoid イシュー ボードに投稿してみてください。その場合は必ずクロスリンクしてください。これについての解決策を見てみたい。

于 2013-01-22T03:05:53.770 に答える