Aby najpierw odpowiedzieć na to pytanie, musisz „obliczyć” liczbę dopasowań do danego warunku, aby „posortować” wyniki, aby powrócić z preferencją do większości dopasowań na górze.
W tym celu potrzebujesz struktury agregacji, której używasz do "obliczania" i "manipulowania" danymi w MongoDB:
db.multiArr.aggregate([
{ "$match": { "Keys": { "$in": [ "carrot", "banana" ] } } },
{ "$project": {
"ID": 1,
"Keys": 1,
"order": {
"$size": {
"$setIntersection": [ ["carrot", "banana"], "$Keys" ]
}
}
}},
{ "$sort": { "order": -1 } }
])
Na MongoDB starszej niż wersja 3, możesz zrobić dłuższą formę:
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 } }
])
W obu przypadkach funkcją tutaj jest najpierw dopasowanie możliwych dokumentów do warunków poprzez dostarczenie "listy" argumentów z $in
. Po uzyskaniu wyników chcesz „policzyć” liczbę pasujących elementów w tablicy do „listy” dostarczonych możliwych wartości.
W nowoczesnej formie $setIntersection
operator porównuje dwie "listy" zwracając nową tablicę, która zawiera tylko "unikalne" pasujące elementy. Ponieważ chcemy wiedzieć, ile było dopasowań, po prostu zwracamy $size
tej listy.
W starszych wersjach tablicę dokumentów rozkładasz za pomocą $unwind
w celu wykonywania na nim operacji, ponieważ w starszych wersjach brakowało nowszych operatorów, które działały z tablicami bez zmian. Następnie proces analizuje każdą wartość indywidualnie i jeśli jedno z wyrażeń w $or
dopasowuje możliwe wartości, a następnie $cond
trójargument zwraca wartość 1
do $sum
akumulator, w przeciwnym razie 0
. Wynik netto to taka sama „liczba dopasowań”, jak pokazano w nowoczesnej wersji.
Ostatnią rzeczą jest po prostu $sort
wyniki są oparte na zwróconej „liczbie dopasowań”, więc najwięcej dopasowań znajduje się na „najwyższym”. To jest "kolejność malejąca" i dlatego podajesz -1
aby to wskazać.
Uzupełnienie dotyczące $in i tablic
Na początek nie rozumiesz kilku rzeczy dotyczących zapytań MongoDB. $in
operator jest właściwie przeznaczony dla "listy" argumentów takich jak ta:
{ "Keys": { "$in": [ "carrot", "banana" ] } }
Co jest zasadniczo skróconym sposobem powiedzenia „Dopasuj „marchewkę” lub „banan” we właściwości „Klucze” . I może być nawet napisany w długiej formie w ten sposób:
{ "$or": [{ "Keys": "carrot" }, { "Keys": "banana" }] }
Co naprawdę powinno Cię prowadzić, gdyby był to warunek dopasowania „pojedynczy”, po prostu podaj wartość do dopasowania do właściwości:
{ "Keys": "carrot" }
Powinno to zakryć błędne przekonanie, że używasz $in
aby dopasować właściwość, która jest tablicą w dokumencie. Przypadek „odwrotny” jest raczej zamierzonym użyciem, w którym zamiast tego podajesz „listę argumentów”, aby dopasować daną właściwość, niezależnie od tego, czy ta właściwość jest tablicą, czy tylko pojedynczą wartością.
Silnik zapytań MongoDB nie rozróżnia pojedynczej wartości lub tablicy wartości w operacji równości lub podobnej.