MongoDB aggregation with unwind on empty array
Answer a question
I have a collection of documents in MongoDB, where each document has a subdocument containing an array.
{
_id: <id>
key1: "value1",
key2: "value2",
...
versions: [
{ version: 2, key1: <othervalue2>, key2: <othervalue2>}
{ version: 1, key1: <othervalue2>, key2: <othervalue2>}
]
}
I want to query the collection and return the document with ALL its fields, along with the elements of the array that match certain parameters (or an empty array when none match). With my current code, I'm only able to get a result when there's AT LEAST one element of the array that matches.
I'm using these parameters for aggregation:
{$match: {_id: <someID>}},
{$unwind: '$versions'},
{$match: {'versions.version': {$gte: <version>}}},
{$group: {_id: '$_id', key1: {$first: '$key1'}, ..., 'versions': {$push: '$versions'}}
For example, querying where arrayelement.version >= 2 should return (this works with the current code):
{
_id: <id>
key1: "value1",
key2: "value2",
...
versions: [
{ version: 2, key1: <othervalue2>, key2: <othervalue2>}
]
}
And querying where arrayelement.version >= 4 should return:
{
_id: <id>
key1: "value1",
key2: "value2",
...
versions: []
}
None of the solutions I have seen address the issue of returning an object even when the array is empty. Is this even possible?
Answers
You can check if versions array is empty and if so add some placeholder, for example an empty document. Omitting rest of the pipeline it could be something like this:
[
{
"$project" : {
"versions" : {
"$cond" : {
"if" : {"$eq" : [{"$size" : "$versions" }, 0]},
"then" : [{ }],
"else" : "$versions"
}
},
"_id" : 1
}
},
{
"$unwind" : "$versions"
}
]
Keep in mind that {$match: {'versions.version'}} in your pipeline will filter it out so you have to adjust this part.
更多推荐
所有评论(0)