Gibbs
Gibbs

Reputation: 22974

MongoDB $addToSet inside another $addToSet

I am trying to achieve the below response from query.

{
  users:[
    user:{
       name:"",
       email:[ 
       ]
    },
    ....user2
  ]
}

I have something similar to below.

I will put this way. One user can have n number of devices. He may have more than one email per device. I want to group at devices. And user field should have common information for that device. As we think, name will always be same. Device specific attributes also needed like whatKindOfDevice, howManyIssuesAreThereInThatDevice, howManyCanBeAddressedByUpgrade, howManyAreRare,etc.. along with this i need to get all the emails used in that device like owner,user,associate - all emails put.

Think my document Id is not associated with single user, single device. One user can have any number of devices. One device can have n Number of documents.

$group:{
   "_id":"user_device_id",
   "user": {
    "$addToSet": {
      "name":"$name",
      "deviceName":"$deviceName",
      "email": {"$addToSet":{}} //Something Similar I am expecting
    }
   }
}

If I add email outer user it works - but it affects the response format required.

Is it possible or any other way to get it the similar response through the query?

Let's assume one user can have more than one document. In each doc, there could be same or duplicate email IDs. I am trying to get that together.

Please advise.

Sample Doc:

{
  _id:ObjectId,
  name:"user1",
  email:"[email protected]"
},
{
  _id:ObjectId,
  name:"user1",
  email:"[email protected]"
},
..user2Doc
..user1Doc with another category, duplicate email i.e [email protected]
..user2Doc with new email
..

Upvotes: 1

Views: 475

Answers (1)

Vijay Rajpurohit
Vijay Rajpurohit

Reputation: 1352

Well, it seems like you want to get all the email for the particular user and then group all the users.

So, to achieve that you have to do consecutive grouping stages.

I used the below documents:

[
{
  name:"user1",
  email:"[email protected]"
},
{
  name:"user1",
  email:"[email protected]"
},
{
  name:"user2",
  email:"[email protected]"
},
{
  name:"user1",
  email:"[email protected]"
}
]

Here is the query:

db.collection.aggregate([
  {
    $group:{
      "_id":"$name",
      "emails":{
        $addToSet:"$email"
      },
      "name":{
        $first:"$name"
      }
    }
  },
  {
    $group:{
      "_id":null,
      "users":{
        $addToSet:{
          "name":"$name",
          "email":"$emails"
        }
      }
    }
  },
  {
    $project:{
      "_id":0
    }
  }
]).pretty()

Output:

{
        "users" : [
                {
                        "name" : "user1",
                        "email" : [
                                "[email protected]",
                                "[email protected]",
                                "[email protected]"
                        ]
                },
                {
                        "name" : "user2",
                        "email" : [
                                "[email protected]"
                        ]
                }
        ]
}

For mare about $group refer here.

Hope this will help :)

Upvotes: 1

Related Questions