Se você quiser "pesar" os resultados por determinados critérios ou ter qualquer tipo de "valor calculado" dentro de uma "classificação", então você precisa do
.aggregate()
método em vez disso. Isso permite que valores "projetados" sejam usados no $sort
operação, para a qual apenas um campo presente no documento pode ser usado:db.messages.aggregate([
{ "$match": { "messages": userId } },
{ "$project": {
"recipients": 1,
"unread": 1,
"content": 1,
"readYet": {
"$setIsSubset": [ [userId], "$unread" ] }
}
}},
{ "$sort": { "readYet": -1 } },
{ "$limit": 20 }
])
Aqui o
$setIsSubset
operador permite a comparação da matriz "não lida" com uma matriz convertida de [userId]
para ver se há alguma correspondência. O resultado será true
onde o userId existe ou false
onde não. Isso pode ser passado para
$sort
, que ordena os resultados com preferência às correspondências ( a classificação decrescente é true
no topo ), e finalmente $limit
apenas retorna os resultados até o valor especificado. Portanto, para usar um termo calculado para "classificar", o valor precisa ser "projetado" no documento para que possa ser classificado. A estrutura de agregação é como você faz isso.
Observe também que
$elemMatch
não é necessário apenas para corresponder a um único valor em uma matriz, e você precisa apenas especificar o valor diretamente. Seu propósito é onde "múltiplas" condições precisam ser atendidas em um único elemento de matriz, o que obviamente não se aplica aqui.