Per rispondere effettivamente prima, devi "calcolare" il numero di corrispondenze alla condizione data per "ordinare" i risultati per tornare con la preferenza al maggior numero di corrispondenze in cima.
Per questo è necessario il framework di aggregazione, che è quello che usi per il "calcolo" e la "manipolazione" dei dati in MongoDB:
db.multiArr.aggregate([
{ "$match": { "Keys": { "$in": [ "carrot", "banana" ] } } },
{ "$project": {
"ID": 1,
"Keys": 1,
"order": {
"$size": {
"$setIntersection": [ ["carrot", "banana"], "$Keys" ]
}
}
}},
{ "$sort": { "order": -1 } }
])
Su un MongoDB precedente alla versione 3, puoi eseguire il modulo più lungo:
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 entrambi i casi la funzione qui è di far corrispondere prima i possibili documenti alle condizioni fornendo una "lista" di argomenti con $in
. Una volta ottenuti i risultati, si desidera "contare" il numero di elementi corrispondenti nell'array nell'"elenco" di possibili valori forniti.
Nella forma moderna il $setIntersection
l'operatore confronta i due "elenchi" restituendo un nuovo array che contiene solo i membri corrispondenti "unici". Dal momento che vogliamo sapere quante corrispondenze erano, restituiamo semplicemente il $size
di quell'elenco.
Nelle versioni precedenti, dividi l'array di documenti con $unwind
per eseguire operazioni su di esso poiché nelle versioni precedenti mancavano gli operatori più recenti che funzionassero con gli array senza alterazioni. Il processo esamina quindi ogni valore individualmente e se una delle espressioni in $or
corrisponde ai valori possibili, quindi $cond
ternario restituisce un valore di 1
al $sum
accumulatore, altrimenti 0
. Il risultato netto è lo stesso "numero di partite" mostrato per la versione moderna.
L'ultima cosa è semplicemente $sort
i risultati in base al "conteggio delle corrispondenze" che è stato restituito, quindi il maggior numero di corrispondenze è in "inizio". Questo è "ordine discendente" e quindi fornisci il -1
per indicarlo.
Addendum riguardante $in e gli array
Per cominciare, stai fraintendendo un paio di cose sulle query MongoDB. Il $in
operatore è effettivamente inteso per un "elenco" di argomenti come questo:
{ "Keys": { "$in": [ "carrot", "banana" ] } }
Che è essenzialmente il modo abbreviato per dire "Abbina 'carota' o 'banana' nella proprietà 'Chiavi'" . E potrebbe anche essere scritto in forma lunga come questa:
{ "$or": [{ "Keys": "carrot" }, { "Keys": "banana" }] }
Il che dovrebbe davvero portarti a se fosse una condizione di corrispondenza "singolare", quindi fornisci semplicemente il valore da abbinare alla proprietà:
{ "Keys": "carrot" }
Quindi questo dovrebbe coprire l'idea sbagliata che usi $in
per abbinare una proprietà che è una matrice all'interno di un documento. Piuttosto il caso "inverso" è l'uso previsto in cui invece fornisci un "elenco di argomenti" per abbinare una determinata proprietà, che sia una proprietà un array o solo un singolo valore.
Il motore di query MongoDB non fa distinzione tra un singolo valore o una matrice di valori in un'operazione di uguaglianza o simile.