$ push è l'aggregazione di null se il campo non è presente. Vorrei evitare questo.
Esiste un modo per rendere un'espressione secondaria per $ push operator in modo tale che i valori nulli vengano saltati e non inseriti nell'array risultante?
$ push è l'aggregazione di null se il campo non è presente. Vorrei evitare questo.
Esiste un modo per rendere un'espressione secondaria per $ push operator in modo tale che i valori nulli vengano saltati e non inseriti nell'array risultante?
Non è del tutto chiaro quale sia il caso specifico senza un esempio. C'è l'operatore $ifNull
che può "sostituire" un valore nullo o un campo mancante con "qualcos'altro", ma non è possibile "saltare" veramente.
Detto questo, è sempre possibile "filtrare" i risultati in base al proprio caso d'uso effettivo.
Se i dati risultante è in realtà un "Set" e si dispone di una versione MongoDB che è 2.6 o superiore, allora è possibile utilizzare $setDifference
con qualche aiuto da $addToSet
per ridurre il numero di null
valori che sono tenuti inizialmente:
db.collection.aggregate([
{ "$group": {
"_id": "$key",
"list": { "$addToSet": "$field" }
}},
{ "$project": {
"list": { "$setDifference": [ "$list", [null] ] }
}}
])
Quindi ci sarebbe solo uno null
e quindi l'operazione $setDifference
lo "filtrerà" nel confronto.
Nelle versioni precedenti o quando i valori non sono in realtà "unica" e non un "set", allora "filtro" per l'elaborazione con $unwind
e $match
:
db.collection.aggregate([
{ "$group": {
"_id": "$key",
"list": { "$push": "$field" }
}},
{ "$unwind": "$list" },
{ "$match": { "list": { "$ne": null } }},
{ "$group": {
"_id": "$_id",
"list": { "$push": "$list" }
}}
])
Se non si desidera di essere "distruttiva" di array, che finirebbero per "vuoto" perché contenevano "nient'altro che" null
, poi si mantiene un uso conteggio $ifNull
e corrispondenza delle condizioni:
db.collection.aggregate([
{ "$group": {
"_id": "$key",
"list": { "$push": "$field" },
"count": {
"$sum": {
"$cond": [
{ "$eq": { "$ifNull": [ "$field", null ] }, null },
0,
1
]
}
}
}},
{ "$unwind": "$list" },
{ "$match": {
"$or": [
{ "list": { "$ne": null } },
{ "count": 0 }
]
}},
{ "$group": {
"_id": "$_id",
"list": { "$push": "$list" }
}},
{ "$project": {
"list": {
"$cond": [
{ "$eq": [ "$count", 0 ] },
{ "$const": [] },
"$list"
]
}
}}
])
Con un finale $project
sostituzione di qualsiasi array che consisteva semplicemente di valori null
solo con un oggetto array vuoto.
po 'tardi per il partito, ma ..
ho voluto fare la stessa cosa, e ha scoperto che ho potuto realizzare con un'espressione così:
// Pushes events only if they have the value 'A'
"events": {
"$push": {
"$cond": [
{
"$eq": [
"$event",
"A"
]
},
"A",
"$noval"
]
}
}
L'idea qui è che quando lo fai
{ "$push": "$event" }
quindi sembra solo spingere valori non nulli.
Quindi ho creato una colonna che non esiste, $ noval, da restituire come condizione falsa del mio $ cond.
Sembra funzionare. Non sono sicuro se non è standard e quindi suscettibile di rompere un giorno, ma ..
Mi hai appena salvato dal crollo del cervello! grazie – mhlavacka