Comportamento non rigoroso di $ nin in mongodb
-
21-12-2019 - |
Domanda
C'è una versione non rigida $ Nin in MongoDB?Ad esempio
Diciamo che abbiamo un modello chiamato Utente e un modello chiamato Task
var TaskSchema = new Schema({
user_array: [{user: Schema.ObjectId}],
});
.
Un campione rapido sarebbe questo
task1 : [user1, user2, user4, user7]
task2 : [user2, user 5, user7]
.
Se ho un elenco di utente
[user1, user7]
.
Voglio selezionare l'attività che ha il minimo sovrapposizione nell'utente_array, in questo caso Task2, conosco $ NIN restituisce rigorosamente il compito che contiene né Utente1 o Utente7, ma vorrei sapere se ci sono operazioni in cui $Nin non è rigoroso.
In alternativa, potrei scrivere una funzione DP per me
Qualsiasi consiglio sarebbe apprezzato
Grazie
Soluzione
Bene in Mongodb versione 2.6 e verso l'alto hai il $setIntersection
< / Strong> e $size
operatori disponibili in modo da poter eseguire un .aggregate()
dichiarazione come questa:
db.collection.aggregate([
{ "$project": {
"user_array": 1,
"size": { "$size": {
"$setIntersection": [ "$user_array", [ "user1", "user7" ] ]
}}
}},
{ "$match": { "size": { "$gt": 1 } },
{ "$sort": { "size": 1 }},
{ "$group": {
"_id": null
"user_array": { "$first": "$user_array" }
}}
])
.
Allora tali operatori aiutano a ridurre i passaggi necessari per trovare il documento meno corrispondente.
Fondamentalmente il $setIntersection
Resi gli elementi corrispondenti nell'array a quello con cui viene confrontato. $size
Operator restituisce la "dimensione "Di quell'array risultante. Quindi, più tardi si filtra con $match
Qualsiasi documento in cui nessuno dei due elementi nella lista corrispondente è stato trovato nell'array.
Alla fine si ordina e restituisci l'oggetto con le partite "minor".
Ma può ancora essere fatto nelle versioni precedenti con altri passaggi. Così fondamentalmente la tua implementazione "non rigida" diventa un $or
Condizione. Ma ovviamente hai ancora bisogno di contare le partite:
db.collection.aggregate([
{ "$project": {
"_id": {
"_id": "$_id",
"user_array": "$user_array"
},
"user_array": 1
}}
{ "$unwind": "$user_array" },
{ "$match": {
"$or": [
{ "user_array": "user1" },
{ "user_array": "user7" }
]
}},
{ "$group": {
"_id": "$_id",
"size": { "$sum": 1 }
}},
{ "$sort": { "size": 1 } },
{ "$group": {
"_id": null,
"user_array": { "$first": "$_id.user_array" }
}}
])
.
e questo farebbe la stessa cosa.