Não é possível reproduzir seu erro, mas você tem alguns "erros de digitação" em sua pergunta, então não posso ter certeza do que você realmente tem.
Mas, presumindo que você realmente esteja trabalhando com o MongoDB 2.6 ou superior, provavelmente deseja o
$setIntersection
ou $setIsSubset
operadores em vez de $setUnion
. Esses operadores implicam o conteúdo "correspondente" do array com o qual são comparados, onde $setUnion
apenas combina a matriz fornecida com a existente:db.people.aggregate([
{ "$project": {
"first_name": 1,
"last_name": 1,
"sticky": {
"$size": {
"$setIntersection": [ "$offices", [ "FL", "SC" ]]
}
},
"offices": 1
}},
{ "$sort": {
"sticky": -1,
"last_name": 1
}}
])
Nas versões anteriores em que você não tem esses operadores de conjunto você está apenas usando
$unwind
para trabalhar com a matriz e o mesmo tipo de $cond
operação como antes dentro de um $group
para trazer tudo de volta:db.people.aggregate([
{ "$unwind": "$offices" },
{ "$group": {
"_id": "$_id",
"first_name": { "$first": "$first_name" },
"last_name": { "$first": "$last_name",
"sticky": { "$sum": { "$cond": [
{ "$or": [
{ "$eq": [ "$offices": "FL" ] },
{ "$eq": [ "$offices": "SC" ] },
]},
1,
0
]}},
"offices": { "$push": "$offices" }
}},
{ "$sort": {
"sticky": -1,
"last_name": 1
}}
])
Mas você certamente estava no caminho certo. Basta escolher a operação de conjunto correta ou outro método para obter sua necessidade precisa.
Ou desde que você postou sua maneira de obter o que deseja, uma maneira melhor de escrever esse tipo de "correspondência ordenada" é esta:
db.people.aggregate([
{ "$project": {
"first_name": 1,
"last_name": 1,
"sticky": { "$cond": [
{ "$anyElementTrue": {
"$map": {
"input": "$offices",
"as": "o",
"in": { "$eq": [ "$$o", "FL" ] }
}
}},
2,
{ "$cond": [
{ "$anyElementTrue": {
"$map": {
"input": "$offices",
"as": "o",
"in": { "$eq": [ "$$o", "SC" ] }
}
}},
1,
0
]}
]},
"offices": 1
}},
{ "$sort": {
"sticky": -1,
"last_name": 1
}}
])
E isso daria prioridade a documentos com "escritórios" contendo "FL" sobre "SC" e, portanto, sobre todos os outros, e fazendo a operação dentro de um único campo. Isso também deve ser muito fácil para as pessoas verem como abstrair isso no formulário usando
$unwind
em versões anteriores sem os operadores de conjunto. Onde você simplesmente fornece o valor de "peso" mais alto para os itens que deseja no topo, aninhando o $cond
declarações.