$ push agreguje wartości null, jeśli pole nie jest obecne. Chciałbym tego uniknąć.
Czy istnieje sposób na wyrażenie podrzędne dla operatora $ push w taki sposób, że wartości puste będą pomijane i niewprowadzane do wynikowej tablicy?
$ push agreguje wartości null, jeśli pole nie jest obecne. Chciałbym tego uniknąć.
Czy istnieje sposób na wyrażenie podrzędne dla operatora $ push w taki sposób, że wartości puste będą pomijane i niewprowadzane do wynikowej tablicy?
To naprawdę nie do końca jasne, jaki jest twój konkretny przypadek bez przykładu. Istnieje operator $ifNull
, który może "zamienić" wartość pustą lub brakujące pole na "coś innego", ale naprawdę "pominięcie" nie jest możliwe.
Powiedziawszy, możesz zawsze "filtrować" wyniki w zależności od rzeczywistego przypadku użycia.
Jeśli uzyskane dane jest rzeczywiście „Set” i masz wersję MongoDB że 2.6 lub nowszej można użyć $setDifference
z pewną pomocą $addToSet
do zmniejszenia liczby null
wartości, które są przechowywane na początku:
db.collection.aggregate([
{ "$group": {
"_id": "$key",
"list": { "$addToSet": "$field" }
}},
{ "$project": {
"list": { "$setDifference": [ "$list", [null] ] }
}}
])
Tak więc będzie tylko jeden null
, a następnie operacja $setDifference
"odfiltruje" to w porównaniu.
We wcześniejszych wersjach lub gdy wartości nie są w rzeczywistości „wyjątkowy”, a nie „set”, a następnie „filtr” przez przetwarzanie z $unwind
i $match
:
db.collection.aggregate([
{ "$group": {
"_id": "$key",
"list": { "$push": "$field" }
}},
{ "$unwind": "$list" },
{ "$match": { "list": { "$ne": null } }},
{ "$group": {
"_id": "$_id",
"list": { "$push": "$list" }
}}
])
Jeśli nie chcesz być „destrukcyjny” tablic, które kończą się „pusty”, ponieważ zawierały one „niczym” null
, a następnie zachować użycie count $ifNull
i mecz na następujących warunkach:
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"
]
}
}}
])
z końcowym $project
zastępowanie dowolnej tablicy, która po prostu składała się z wartości tylko z pustym obiektem tablicy.
Bit późno do partii, ale ..
chciałem zrobić to samo, i okazało się, że mogę wykonać go z wyrazem jak ten:
// Pushes events only if they have the value 'A'
"events": {
"$push": {
"$cond": [
{
"$eq": [
"$event",
"A"
]
},
"A",
"$noval"
]
}
}
Myślenie jest to, że kiedy robisz
wtedy wydaje się, że tylko wypychasz wartości inne niż null.
Więc wymyśliłem kolumnę, która nie istnieje, $ noval, która zostanie zwrócona jako fałszywy warunek mojego dolara.
Wydaje się działać. Nie jestem pewien, czy to jest niestandardowe, a zatem podatne na złamanie jednego dnia, ale ..
Właśnie uratowałeś mnie od krachu mózgu! dzięki – mhlavacka