Reputation: 3659
I have the following array of collection of books. I'm trying to project a single property of an element in an array.
My query is projecting the text property in comments array for book
of year 2012
for author A1
.
Example books array:
[
{
book_id: "1",
title:'B1',
year: 2012,
comments: [
{
author: "A1",
text: "C1"
}
]
},
{
book_id: "2",
title:'B2',
year: 2012,
comments: [
{
author: "A2",
text: "C2.0"
},
{
author: "A1",
text: "C2.1"
},
{
author: "A1",
text: "C2.2"
},
]
},
{
book_id: "3",
title:'B3',
year: 2013,
comments: [
{
author: "A1",
text: "C3"
}
]
},
]
expected result
[
"C1",
"C2.1",
"C2.2"
]
I tried the following:
// query using find
db.books.find(
{year:2012, comments: {$elemMatch : {author:"A1" } } },{_id:0,'comments.text':1}
)
// results
/* 1 */
{
"comments" : [
{
"text" : "C1"
}
]
}
/* 2 */
{
"comments" : [
{
"text" : "C2.0"
},
{
"text" : "C2.1"
},
{
"text" : "C2.2"
}
]
}
// query using aggregation
db.books.aggregate(
[
{$match: {year:2012}},
{
$project:{
comments: {
$filter:{
input: "$comments",
as:'comment',
cond: {$eq:['$$comment.author','A1']}
}
}
}
}
])
// results in
/* 1 */
{
"_id" : ObjectId("5d3446f9d9eac0ed968aad4b"),
"comments" : [
{
"author" : "A1",
"text" : "C1"
}
]
}
/* 2 */
{
"_id" : ObjectId("5d3446f9d9eac0ed968aad4c"),
"comments" : [
{
"author" : "A1",
"text" : "C2.1"
},
{
"author" : "A1",
"text" : "C2.2"
}
]
}
Upvotes: 2
Views: 2228
Reputation: 46491
You can use below aggregation
db.collection.aggregate([
{ "$match": { "year": 2012, "comments": { "$elemMatch": { "author": "A1" }}}},
{ "$unwind": "$comments" },
{ "$match": { "year": 2012, "comments.author": "A1" }},
{ "$group": {
"_id": null,
"data": { "$push": "$comments.text" }
}}
])
[
{
"_id": null,
"data": [
"C1",
"C2.1",
"C2.2"
]
}
]
You cannot return simple array string with mongodb because it only returns the BSON document rather than just array of elements.
Upvotes: 4