I have a collection that contains docs of following structure:
{
"_id" : ObjectId("547b4b4ba7d3aef3bdbc5e1c"),
"title" : "article1",
"comments" : [
{
"text" : "first comment",
"createdAt" : ISODate("2014-11-30T16:52:24.032Z")
}
],
"pictures" : [
{
"url" : "http://example.com/1.jpg",
"isPrimary" : false
},
{
"url" : "http:example.com/2.jpg",
"isPrimary" : true
},
{
"url" : "http://example.com/3.jpg"
}
]
}
I need to pull all documents and exclude non-primary pictures using single query. Ie output should be:
{
"_id" : ObjectId("547b4b4ba7d3aef3bdbc5e1c"),
"title" : "article1",
"comments" : [
{
"text" : "first comment",
"createdAt" : ISODate("2014-11-30T16:52:24.032Z")
}
],
"pictures" : [
{
"url" : "http:example.com/2.jpg",
"isPrimary" : true
}
]
}
Or even better if "pictures" will contains document instead of array:
...
"pictures" : {
"url" : "http:example.com/2.jpg",
"isPrimary" : true
}
...
I tried aggregate and $redact, but it doesn't work because the document and the comments sub-doc don't have 'isPrimary' field.
Use $unwind
in Aggregation Framework :
db.collection.aggregate([
{ $project: {
_id: 1,
title: 1,
comments: 1,
pictures: {
$cond : [
// if pictures is null or does not exists, project it to []
{ $eq : [ { $ifNull: [ "$pictures", [] ] } , [] ] },
// if pictures is [] then project it to a list with one fake empty picture with isPrimary set to true
[ { isPrimary: true, _empty: true } ],
// otherwise project it to just the original pictures property
"$pictures"
] }
} },
{ $unwind: "$pictures" },
{ $match: { "pictures.isPrimary": true } },
{ $group: {
_id: "$_id",
title: { $first: "$title" },
comments: { $first: "$comments" },
picture: { $first: "$pictures" }
} },
{ $project: {
_id: 1,
title: 1,
comments: 1,
// filter out the fake isPrimary pictures that were added in the initial projection
picture: { $cond: [ { $eq: [ "$picture._empty", true ] }, {}, "$picture" ] }
} }
])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.