5

演算子を使用してmongodbfindクエリを実行しています$in

collection.find({name: {$in: [name1, name2, ...]}})

名前の配列と同じ順序で結果を並べ替えたいのですが[name1, name2, ...]。どうすればこれを達成できますか?

注:私はpymongoを介してMongoDbにアクセスしていますが、それは重要ではないと思います。

編集:MongoDbでこれをネイティブに実現することは不可能であるため、私は典型的なPythonソリューションを使用することになりました:

names = [name1, name2, ...]
results = list(collection.find({"name": {"$in": names}}))
results.sort(key=lambda x: names.index(x["name"]))
4

3 に答える 3

5

これは、次のバージョン3.4(2016年11月)以降の集約フレームワークで実現できます。

order=["David", "Charlie", "Tess"]必要な順序が、このパイプラインを介して実行する配列であると想定します。

m = { "$match" : { "name" : { "$in" : order } } };
a = { "$addFields" : { "__order" : { "$indexOfArray" : [ order, "$name" ] } } };
s = { "$sort" : { "__order" : 1 } };
db.collection.aggregate( m, a, s );

この"$addFields"ステージは3.4の新機能であり"$project"、他のすべての既存のフィールドを知らなくても、既存のドキュメントに新しいフィールドを追加できます。新しい "$indexOfArray"式は、指定された配列内の特定の要素の位置を返します。

この集計の結果は、入力配列orderで指定された順序で、条件に一致するドキュメントになります。ドキュメントには、すべての元のフィールドに加えて、と呼ばれる追加のフィールドが含まれます。__order

于 2016-10-24T20:04:13.680 に答える
2

不可能。$in演算子は存在を確認します。リストはセットとして扱われます。

オプション:

  • name1 ... nameNの複数のクエリに分割するか、同じ方法で結果をフィルタリングします。より多くの名前-より多くのクエリ。
  • itertools groupby/ifilterを使用します。その場合、すべてのドキュメントに「並べ替えの優先順位」フラグを追加し、name1をPREC1に、name2をPREC2に、....、次にPRECでソートし、次にPRECでグループ化します。

コレクションに「名前」フィールドのインデックスがある場合は、オプション1の方が適しています。インデックスがない場合、または書き込み/読み取り比率が高いためにインデックスを作成できない場合は、オプション2が適しています。

于 2013-02-04T11:11:11.513 に答える
2

Vitalyは正しいですが、findでそれを行うことは不可能ですが、集計で実現できます。

db.collection.aggregate( [ { $match: { name: {$in: [name1, name2, ...]} }, { $project: { 'name': 1, 'name1': { $eq: [ 'name1', '$name' ] }, 'name2': { $eq: [ 'name2', '$name' ] } } }, { $sort: { 'name1': 1, 'name2': 1 } } ] )

2.6.5でテスト済み

これが他の人々を正しい方向に導くことを願っています。

于 2014-12-22T01:52:18.290 に答える