Reputation: 45
My mongo db data is like
{ "_id" : ObjectId("58e879052b614ce778fb7af2"), "email" : "[email protected]", "phone" : 1234 }
{ "_id" : ObjectId("58e879052b614ce778fb7af3"), "email" : "[email protected]", "phone" : 2346 }
{ "_id" : ObjectId("58e879052b614ce778fb7af4"), "email" : "[email protected]", "phone" : 7896 }
{ "_id" : ObjectId("58e879052b614ce778fb7af5"), "phone" : 5789, "email" : "[email protected]" }
{ "_id" : ObjectId("58e879052b614ce778fb7af6"), "phone" : 7896, "email" : "[email protected]" }
{ "_id" : ObjectId("58e879052b614ce778fb7af7"), "phone" : 3492, "email" : "[email protected]" }
{ "_id" : ObjectId("58e879052b614ce778fb7af8"), "phone" : 5555, "email" : "[email protected]" }
{ "_id" : ObjectId("58e87ea96774f88e108b4567"), "phone" : 5789, "email" : "[email protected]" }
{ "_id" : ObjectId("58e880db6774f8130f8b4567"), "phone" : 5789, "email" : "" }
{ "_id" : ObjectId("58e880e56774f81f108b4567"), "phone" : 1234, "email" : "" }
{ "_id" : ObjectId("58e880f96774f83b108b4567"), "phone" : 9846, "email" : "" }
{ "_id" : ObjectId("58e881016774f83b108b4568"), "phone" : 1012, "email" : "" }
{ "_id" : ObjectId("58e8812a6774f8c0108b4567"), "phone" : 1258 }
{ "_id" : ObjectId("58e881496774f80e108b4567"), "phone" : 1012, "email" : "" }
I want to group first based on the email anf then by using phone.
{ "_id" : ObjectId("58e879052b614ce778fb7af2"), "email" : "[email protected]", "phone" : 1234 }
{ "_id" : ObjectId("58e879052b614ce778fb7af3"), "email" : "[email protected]", "phone" : 2346 }
{ "_id" : ObjectId("58e879052b614ce778fb7af6"), "phone" : 7896, "email" : "[email protected]" }
{ "_id" : ObjectId("58e879052b614ce778fb7af7"), "phone" : 3492, "email" : "[email protected]" }
{ "_id" : ObjectId("58e879052b614ce778fb7af8"), "phone" : 5555, "email" : "[email protected]" }
{ "_id" : ObjectId("58e880f96774f83b108b4567"), "phone" : 9846, "email" : "" }
{ "_id" : ObjectId("58e881016774f83b108b4568"), "phone" : 1012, "email" : "" }
{ "_id" : ObjectId("58e8812a6774f8c0108b4567"), "phone" : 1258 }
I want all the email ids except the null values with correcsponding phone numbers. Also want Phone numbers which doesn't have the same email ids as of the group email. Phone numbers with null email id or without key email also should be included in the output.
Thanking you.
Upvotes: 0
Views: 137
Reputation: 5212
You need $group and $first aggregate command, to group by email and then phone you must use $cond with a final $project to clean up.
db.data.aggregate([ {$group: {_id: {$cond: {if: {"$eq": ['$email', '']}, else: {email: '$email'}, then: {phone: '$phone', email: '$email'}}}, firstId: {$first: '$_id'}, phone: {$first: '$phone'}}}, {$project: {_id: '$firstId', phone: '$phone', email: '$_id.email'}} ])
{ "_id" : ObjectId("58e880f96774f83b108b4567"), "phone" : 9846, "email" : "" }
{ "_id" : ObjectId("58e881016774f83b108b4568"), "phone" : 1012, "email" : "" }
{ "_id" : ObjectId("58e880e56774f81f108b4567"), "phone" : 1234, "email" : "" }
{ "_id" : ObjectId("58e880db6774f8130f8b4567"), "phone" : 5789, "email" : "" }
{ "_id" : ObjectId("58e879052b614ce778fb7af8"), "phone" : 5555, "email" : "[email protected]" }
{ "_id" : ObjectId("58e879052b614ce778fb7af6"), "phone" : 7896, "email" : "[email protected]" }
{ "_id" : ObjectId("58e879052b614ce778fb7af7"), "phone" : 3492, "email" : "[email protected]" }
{ "_id" : ObjectId("58e879052b614ce778fb7af3"), "phone" : 2346, "email" : "[email protected]" }
{ "_id" : ObjectId("58e8812a6774f8c0108b4567"), "phone" : 1258 }
{ "_id" : ObjectId("58e879052b614ce778fb7af2"), "phone" : 1234, "email" : "[email protected]" }
db.data.aggregate([
{$group: {_id: '$phone', emails: {$addToSet: {email: '$email', _id: '$_id'}}, countNonBlank: {$sum: {$cond: [{$eq: ['$email', '']}, 0, 1]}}}}, {$unwind: {path: '$emails', preserveNullAndEmptyArrays: true}},
{$match: {$or: [{'emails.email': {$ne: ''}}, {"countNonBlank": {$lt: 1}, "emails.email": {$eq: ''}}]}},
{$project: {phone: '$_id', email: '$emails.email', _id: '$emails._id'}},
{$group: {_id: {email: '$email', phone: '$phone'}, firstId: {$first: '$_id'}}},
{$project: {_id: '$firstId', phone: '$_id.phone', email: '$_id.email'}},
{$group: {_id: {$cond: {if: {"$eq": ['$email', '']}, else: {email: '$email'}, then: {phone: '$phone', email: '$email'}}}, firstId: {$first: '$_id'}, phone: {$first: '$phone'}}},
{$project: {_id: '$firstId', phone: '$phone', email: '$_id.email'}}
])
{ "_id" : ObjectId("58e881496774f80e108b4567"), "phone" : 1012, "email" : "" }
{ "_id" : ObjectId("58e880f96774f83b108b4567"), "phone" : 9846, "email" : "" }
{ "_id" : ObjectId("58e879052b614ce778fb7af3"), "phone" : 2346, "email" : "[email protected]" }
{ "_id" : ObjectId("58e879052b614ce778fb7af7"), "phone" : 3492, "email" : "[email protected]" }
{ "_id" : ObjectId("58e879052b614ce778fb7af6"), "phone" : 7896, "email" : "[email protected]" }
{ "_id" : ObjectId("58e879052b614ce778fb7af8"), "phone" : 5555, "email" : "[email protected]" }
{ "_id" : ObjectId("58e8812a6774f8c0108b4567"), "phone" : 1258 }
{ "_id" : ObjectId("58e879052b614ce778fb7af2"), "phone" : 1234, "email" : "[email protected]" }
Upvotes: 1