Vaidhy
Vaidhy

Reputation: 177

Complex aggregation query with in clause from document array

Below is the sample MongoDB Data Model for a user collection:

{
    "_id": ObjectId('58842568c706f50f5c1de662'),
    "userId": "123455",
    "user_name":"Bob"
    "interestedTags": [
        "music",
        "cricket",
        "hiking",
        "F1",
        "Mobile",
        "racing"
    ],
    "listFriends": [
        "123456",
        "123457",
        "123458"
    ]
}

listFriends is an array of userId for other users

For a particular userId I need to extract the listFriends (userId's) and for those userId's I need to aggregate the interestedTags and their count.

I would be able to achieve this by splitting the query into two parts:

1.) Extract the listFriends for a particular userId,

2.) Use this list in an aggregate() function, something like this

db.user.aggregate([
    { $match: { userId: { $in: [ "123456","123457","123458" ] } } }, 
    { $unwind: '$interestedTags' },
    { $group: { _id: '$interestedTags', countTags: { $sum : 1 } } }
])

I am trying to solve the question: Is there a way to achieve the above functionality (both steps 1 and 2) in a single aggregate function?

Upvotes: 2

Views: 1929

Answers (1)

kkkkkkk
kkkkkkk

Reputation: 7738

You could use $lookup to look for friend documents. This stage is usually used to join two different collection, but it can also do join upon one single collection, in your case I think it should be fine:

db.user.aggregate([{
  $match: {
    _id: 'user1',
  }
}, {
  $unwind: '$listFriends',
}, {
  $lookup: {
    from: 'user',
    localField: 'listFriends',
    foreignField: '_id',
    as: 'friend',
  }
}, {
  $project: {
    friend: {
      $arrayElemAt: ['$friend', 0]
    }
  }
}, {
  $unwind: '$friend.interestedTags'
}, {
  $group: {
    _id: '$friend.interestedTags',
    count: {
      $sum: 1
    }
  }
}]);

Note: I use $lookup and $arrayElemAt which are only available in Mongo 3.2 or newer version, so check your Mongo version before using this pipeline.

Upvotes: 4

Related Questions