Reputation: 2837
I have a MongoDB collection, Groups. Each group has an array of members, referenced by the member's unique id. A user can be a member of many groups.
Group data looks like this:
{ _id: 1, members: ['1', '3', '5'], status: 'active' }
{ _id: 2, members: ['4', '1', '10', '11'], status: 'inactive' }
{ _id: 3, members: ['1', '2', '9'], status: 'active' }
I'm trying to extract all members of active groups as a single array of member ids, without duplication. I want to export them to a csv file using mongoexport.
I can export the ids of the relevant projects and their member lists:
mongoexport -h localhost:3001 --db mydbname --collection groups --type=csv --fields _id,members --query '{"status": "active"}' --out mongotestoutput.txt
But I can't figure out how to merge the member lists into a single array. I've been looking at Aggregation but I'm just getting lost among all the different options, I can't see which one would do what I need. Very grateful for any help.
Upvotes: 1
Views: 1959
Reputation: 4052
Use aggregation with $unwind
and then $out
to create a new collection that looks like you need. Then export this new collection to CSV file.
db.test1.insertMany([
{ _id: 1, members: ['1', '3', '5'], status: 'active' },
{ _id: 2, members: ['4', '1', '10', '11'], status: 'inactive' },
{ _id: 3, members: ['9'], status: 'active' }
])
{_id:0}
here and below is used to suppress _id field
db.test1.aggregate([
{$unwind: "$members"},
{$project:{_id:0}},
{$out:"test2"}
])
db.test2.find({},{_id:0})
{ "members" : "1", "status" : "active" }
{ "members" : "3", "status" : "active" }
{ "members" : "5", "status" : "active" }
{ "members" : "4", "status" : "inactive" }
{ "members" : "1", "status" : "inactive" }
{ "members" : "10", "status" : "inactive" }
{ "members" : "11", "status" : "inactive" }
{ "members" : "9", "status" : "active" }
Or if you need to get members by status in the array - add another $group
, $addToSet
stage:
db.test1.aggregate([
{$unwind: "$members"},
{$project:{_id:0}},
{ "$group": { "_id": "$status", members:{$addToSet:"$members"} } },
{$out:"test3"}
])
db.test3.find()
{ "_id" : "inactive", "members" : [ "4", "1", "10", "11" ] }
{ "_id" : "active", "members" : [ "1", "3", "5", "9" ] }
See MongoPlayground
Upvotes: 1
Reputation: 2837
This question shows two ways to get the result I'm looking for. The accepted answer uses push, reduce and setUnion. The newer answer is simpler, using unwind and addToSet. Both work for me but I'm going with the simpler version:
db.collection.aggregate([
{ $match: { "status": "active" },
{ $unwind: "$members"},
{ $group:{
_id: 0,
selectedMembers: { $addToSet: '$members' }
}}
])
I'm extracting the array I want from the JSON object returned by this expression.
Upvotes: 0