Para realmente responder isso primeiro, você precisa "calcular" o número de correspondências para a condição dada para "ordenar" os resultados para retornar com a preferência para a maioria das correspondências no topo.
Para isso você precisa do framework de agregação, que é o que você usa para "cálculo" e "manipulação" de dados no MongoDB:
db.multiArr.aggregate([
{ "$match": { "Keys": { "$in": [ "carrot", "banana" ] } } },
{ "$project": {
"ID": 1,
"Keys": 1,
"order": {
"$size": {
"$setIntersection": [ ["carrot", "banana"], "$Keys" ]
}
}
}},
{ "$sort": { "order": -1 } }
])
Em um MongoDB anterior à versão 3, você pode fazer a forma mais longa:
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 } }
])
Em ambos os casos, a função aqui é primeiro combinar os documentos possíveis com as condições, fornecendo uma "lista" de argumentos com
$in
. Uma vez que os resultados são obtidos, você deseja "contar" o número de elementos correspondentes na matriz para a "lista" de valores possíveis fornecidos. Na forma moderna, o
$setIntersection
O operador compara as duas "listas" retornando uma nova matriz que contém apenas os membros correspondentes "exclusivos". Como queremos saber quantas correspondências foram, simplesmente retornamos o $size
dessa lista. Em versões mais antigas, você separa o array de documentos com
$unwind
para realizar operações nele, pois as versões mais antigas não possuíam os operadores mais recentes que trabalhavam com arrays sem alterações. O processo então examina cada valor individualmente e se qualquer expressão em $or
corresponde aos valores possíveis, então o $cond
ternário retorna um valor de 1
para o $sum
acumulador, caso contrário 0
. O resultado líquido é a mesma "contagem de partidas" mostrada na versão moderna. A última coisa é simplesmente
$sort
os resultados com base na "contagem de correspondências" que foi retornada para que a maioria das correspondências fique no "topo". Esta é uma "ordem decrescente" e, portanto, você fornece o -1
para indicar isso. Adendo sobre $in e arrays
Você está entendendo mal algumas coisas sobre as consultas do MongoDB para iniciantes. O
$in
na verdade, o operador destina-se a uma "lista" de argumentos como este:{ "Keys": { "$in": [ "carrot", "banana" ] } }
Que é essencialmente a forma abreviada de dizer "Combine 'cenoura' ou 'banana' na propriedade 'Chaves'" . E poderia até ser escrito em formato longo assim:
{ "$or": [{ "Keys": "carrot" }, { "Keys": "banana" }] }
O que realmente deveria levar você a se fosse uma condição de correspondência "singular", então você simplesmente fornece o valor para corresponder à propriedade:
{ "Keys": "carrot" }
Então isso deve cobrir o equívoco de que você usa
$in
para corresponder a uma propriedade que é uma matriz em um documento. Em vez disso, o caso "reverso" é o uso pretendido onde, em vez disso, você fornece uma "lista de argumentos" para corresponder a uma determinada propriedade, seja essa propriedade uma matriz ou apenas um valor único. O mecanismo de consulta do MongoDB não faz distinção entre um valor único ou uma matriz de valores em uma operação de igualdade ou similar.