I have some document with this structure - the category field can also be empty
{
"_id" : "1",
"category" : [
{ "target" : "element 1" },
{ "target" : "element 2" }
]
},
{
"_id" : "2",
"category" : [
{ }
]
},
{
"_id" : "3",
"category" : [
{ "target" : "element 1" },
{ "target" : "element 2" }
]
},
What I need is a result like
{ id: 1, element: "element 1" },
{ id: 1, element: "element 2" },
{ id: 3, element: "element 1" },
{ id: 3, element: "element 2" }
That means first I have to check for all documents which have target elements:
var result = db.collection.find({}, { 'category.target': 1})
1) But this doesn't work, as I still get the empty doc (2).
2) Second I need to get a new result element for each element in the target-array. I think aggregate isn't the correct way as there has to be new objects for each element. And map is only to nave the fields.
So I think I have to iterate over the results and build a new object, correct?
result.forEach(function($res){
// do a new foreach for every element in target-array?
newResult.push({ id: res._id, element: res.element });
});
You can do this usingaggregate
which, unlike find
, allows you to reshape documents.
db.test.aggregate([
// Duplicate each doc, once per category element
{$unwind: '$category'},
// Reshape the documents to create the element field
{$project: {element: '$category.target'}},
// Only include docs with an element
{$match: {element: {$exists: true}}}
])
Result:
"result" : [
{
"_id" : "1",
"element" : "element 1"
},
{
"_id" : "1",
"element" : "element 2"
},
{
"_id" : "3",
"element" : "element 1"
},
{
"_id" : "3",
"element" : "element 2"
}
]
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.