Reputation: 540
Is there a way to project fields that may or may not exist? Such as having it defined as null
or undefined?
For instance, I have a query with:
$project: {
date: 1,
name: "$person.name",
age: "$person.age"
}
Not all documents are guaranteed to have a $person.age
, but instead of the ones without an age being returned as { date: Today, name: "Bill" }
, I would like it to say { date: Today, name: "Bill", age: null }
or something similar.
Is there a better way than just iterating through the data afterwards and creating the fields if they don't exist?
Upvotes: 25
Views: 22941
Reputation: 61666
Starting in Mongo 5.3
, it's a nice use case for the new $fill
aggregation operator:
// { name: "Bill", age: 23 }
// { name: "Peter" }
db.collection.aggregate(
{ $fill: { output: { age: { value: "Unspecified" } } } }
)
// { name: "Bill", age: 23 }
// { name: "Peter", age: "Unspecified" }
Missing values or values set to null
are fill
ed with the given constant Unspecified
.
Concerning your exact scenario, you can go for:
// { person: { name: "Bill", age: 23 } }
// { person: { name: "Peter" } }
db.collection.aggregate([
{ $project: { name: "$person.name" , age: "$person.age" } },
{ $fill: { output: { "age": { value: "Unspecified" } } } }
])
// { name: "Bill", age: 23 }
// { name: "Peter", age: "Unspecified" }
Upvotes: 4
Reputation: 13640
Use $ifNull
$project: {
date: 1,
name: "$person.name",
age: { $ifNull: [ "$person.age", "null" ] }
}
You can find more about it here
Upvotes: 52
Reputation: 103375
This is where $ifNull
expression comes into the fray. From the docs, $ifNull
:
Evaluates an expression and returns the value of the expression if the expression evaluates to a non-null value. If the expression evaluates to a null value, including instances of undefined values or missing fields, returns the value of the replacement expression.
In your case, the following will use the $ifNull
expression to return either the non-null $person.age
field value or the string "Unspecified" if the age field is null or does not exist:
$project: {
date: 1,
name: "$person.name",
age: { $ifNull: [ "$person.age", "Unspecified" ] }
}
Upvotes: 3