2017-02-17 8 views
4

MongoDBの非常に奇妙な動作を見つけました。私のテストケースでは、9つのドキュメントを持つMongoDBコレクションがあります。すべての文書は、フィールドexpired_at: Dateおよびlocation: [lng, lat]を含む完全に同じ構造を持っています。

これで、期限切れではなく、バウンディングボックス内にあるすべてのドキュメントを見つける必要があります。マップ上に一致する文書を表示します。有効期限は、過去に長いので

var qExpiry = {"expired_at": { $gt : new Date() } }; 
var qLocation = { "location" : { $geoWithin : { $box : [ [ 123.8766, 8.3269 ] , [ 122.8122, 8.24974 ] ] } } }; 
var qFull = { $and: [ qExpiry, qLocation ] }; 

、と私は十分な大きさのバウンディングボックスを設定すると、次のクエリは、予想通り、すべての9つのドキュメント私を与える:このために私は次のクエリを設定

db.docs.find(qExpiry); 
db.docs.find(qLocation); 
db.docs.find(qFull); 
db.docs.find(qExpiry).sort({"created_at" : -1}); 
db.docs.find(qLocation).sort({"created_at" : -1}); 

は今ここに取り引きです:次のクエリが0のドキュメントを戻します。

db.docs.find(qFull).sort({"created_at" : -1}); 

だけに並べ替えを追加し、クエリが、私はまた、李を持っているので、ソートすることに注意してください(結果遺跡地図を乱雑にするのを避けるために、より大きなスケールでのミット)。他のフィールドでソートすると、同じ空の結果が得られます。何が起きてる?

(実際にも、見知らぬ人:。。私は私のマップにズームすると、私は時には仕分けで、qFullの結果を得る一つはqLocationに障害があると主張する可能性がしかし、私は唯一のqLocationを使用し、結果は常に正しく、qExpiry。とにかくすべての文書のために常に真です)

+2

アグリゲーションフレームワークの '$ match'と' $ sort'パイプラインを使って同じクエリを実行しようとしましたか? – chridam

+0

@chridam - うわー、それはトリックでした!私はこれが他の人と同様に遭遇するかもしれないので、答えを提供します。なぜこの方法が機能し、私の初期のアプローチではないかというアイデアはありますか? – Christian

答えて

2

db.docs.aggregate([ 
    { 
     "$match": { 
      "expired_at": { "$gt" : new Date() }, 
      "location" : { 
       "$geoWithin" : { 
        "$box" : [ 
         [ 123.8766, 8.3269 ], 
         [ 122.8122, 8.24974 ] 
        ] 
       } 
      } 
     } 
    }, 
    { "$sort": { "created_at": -1 } } 
]); 

find()

1

MongoDBの集約フレームワークを使用してchridamの提案が行く方法であることが判明しました。私の作業クエリは次のようになります。

db.docs.aggregate(
    [ 
     { $match : { $and : [qExpiry, qLocation]} }, 
     { $sort: {"created_at": -1} }. 
     { $limit: 50 }. 
    ] 
); 

しかし、私の最初のアプローチがうまくいかなかったと指摘できれば、非常に便利です。空でないクエリにsort()を追加するだけで、突然0個のドキュメントが返されてはなりません。追加するだけですが、まだ少しでも試してみましたので、.sort({})はすべてのドキュメントを返しますが、あまり役に立ちませんでした。その他はすべて.sort({'_id': 1})など失敗しました。

db.docs.aggregate([ 
    { "$match": qFull }, 
    { "$sort": { "created_at": -1 } } 
]); 

または暗黙のように式のコンマ区切りリストをspecifiyingによって$andを使用して:あなたは集約フレームワークの$match$sortパイプラインを使用して、同じクエリを実行しようとする場合があります

関連する問題