За да отговорите действително на това първо, трябва да „изчислите“ броя на съвпаденията на даденото условие, за да „сортирате“ резултатите, за да се върнете с предпочитание към най-много съвпадения отгоре.
За това се нуждаете от рамката за агрегиране, която използвате за „изчисление“ и „манипулиране“ на данни в MongoDB:
db.multiArr.aggregate([
{ "$match": { "Keys": { "$in": [ "carrot", "banana" ] } } },
{ "$project": {
"ID": 1,
"Keys": 1,
"order": {
"$size": {
"$setIntersection": [ ["carrot", "banana"], "$Keys" ]
}
}
}},
{ "$sort": { "order": -1 } }
])
На MongoDB, по-стара от версия 3, тогава можете да направите по-дългата форма:
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
оператор сравнява двата "списъка", връщайки нов масив, който съдържа само "уникалните" съвпадащи членове. Тъй като искаме да знаем колко съвпадения е било, просто връщаме $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 не прави разлика между една стойност или масив от стойности в операция за равенство или подобна операция.