これに実際に最初に答えるには、特定の条件に一致する数を「計算」して、結果を「並べ替え」、最上位の一致を優先して返す必要があります。
このためには、MongoDBのデータの「計算」と「操作」に使用する集約フレームワークが必要です。
db.multiArr.aggregate([
{ "$match": { "Keys": { "$in": [ "carrot", "banana" ] } } },
{ "$project": {
"ID": 1,
"Keys": 1,
"order": {
"$size": {
"$setIntersection": [ ["carrot", "banana"], "$Keys" ]
}
}
}},
{ "$sort": { "order": -1 } }
])
バージョン3より古いMongoDBでは、より長い形式を実行できます:
db.multiArr.aggregate([
{ "$match": { "Keys": { "$in": [ "carrot", "banana" ] } } },
{ "$unwind": "$Keys" },
{ "$group": {
"_id": "$_id",
"ID": { "$first": "$ID" },
"Keys": { "$push": "$Keys" },
"order": {
"$sum": {
{ "$cond": [
{ "$or": [
{ "$eq": [ "$Keys", "carrot" ] },
{ "$eq": [ "$Keys", "banana" ] }
]},
1,
0
]}
}
}
}},
{ "$sort": { "order": -1 } }
])
いずれの場合も、ここでの関数は、$in
を使用して引数の「リスト」を提供することにより、最初に可能なドキュメントを条件に一致させることです。 。結果が得られたら、配列内の一致する要素の数を、提供された可能な値の「リスト」に「カウント」します。
現代の形式では、$setIntersection
演算子は、2つの「リスト」を比較して、「一意の」一致するメンバーのみを含む新しい配列を返します。一致した数を知りたいので、$size
を返すだけです。 そのリストの。
古いバージョンでは、$unwind
を使用してドキュメント配列を分解します 古いバージョンには、変更せずに配列を操作する新しい演算子がなかったため、操作を実行するため。次に、プロセスは各値を個別に調べ、$or
のいずれかの式かどうかを調べます。 可能な値と一致し、$cond
ternaryは1
の値を返します $sum
に アキュムレータ、それ以外の場合は0
。最終的な結果は、最新バージョンで示されているのと同じ「一致数」になります。
最後に、$sort
を実行します。 返された「一致数」に基づく結果であるため、最も多くの一致が「トップ」になります。これは「降順」であるため、-1
を指定します それを示すために。
$inと配列に関する補遺
初心者向けのMongoDBクエリについていくつか誤解しています。 $in
演算子は、実際には次のような引数の「リスト」を対象としています。
{ "Keys": { "$in": [ "carrot", "banana" ] } }
これは基本的に、「'ニンジン'またはのいずれかに一致する」と言う簡単な方法です。 プロパティ「キー」の「バナナ」 。そして、次のように長い形式で書くこともできます:
{ "$or": [{ "Keys": "carrot" }, { "Keys": "banana" }] }
これが「単一の」一致条件である場合に実際につながるはずです。次に、プロパティに一致する値を指定するだけです。
{ "Keys": "carrot" }
これで、$in
を使用するという誤解をカバーする必要があります ドキュメント内の配列であるプロパティと一致します。むしろ、「逆」の場合は、特定のプロパティに一致する「引数のリスト」を提供するという意図された使用法であり、そのプロパティは配列または単一の値です。
MongoDBクエリエンジンは、同等または同様の操作で単一の値または値の配列を区別しません。