每个用户仅获取一个文档-mongoDB

时间:2018-09-20 08:30:37

标签: node.js mongodb mongoose aggregation-framework

我陷入了mongo聚合查询。现在,我有一个收藏集,其中包含各种用户的帖子(这些详细信息出现在用户收藏集中)。

我需要一个查询来仅获取每个用户的一个帖子(例如SQL中的分组依据)

POSTS收集数据

{
  language:'english',
  status:'A',
  desc:'Hi there',
  userId:'5b891370f43fe3302bbd8918'
},{
  language:'english',
  status:'A',
  desc:'Hi there - 2'
  userId:'5b891370f43fe3302bbd8918'
},{
  language:'english',
  status:'A',
  desc:'Hi there - 3'
  userId:'5b891370f43fe3302bbd8001'
}

这是我的查询

db.col('posts').aggregate([
    {
        $match: {
            language: 'english',
            status: "A"
        }
    }, {
        $sample: { size: 10 }
    }, {
        $sort: { _id: -1 }
    }, {
        $lookup: {
            from: 'users',
            localField: 'userId',
            foreignField: '_id',
            as: 'ownerData'
        }
    }], (err, data) => { console.log(err,data) });

所需的输出

   {
      language:'english',
      status:'A',
      desc:'Hi there',
      userId:'5b891370f43fe3302bbd8918',
      ownerData:[[object]]
    },{
      language:'english',
      status:'A',
      desc:'Hi there - 3'
      userId:'5b891370f43fe3302bbd8001',
      ownerData:[[object]]
    }

3 个答案:

答案 0 :(得分:3)

$ group :将作为mysql的group by。 $ first :将从组中获取集合字段的第一个元素。 $ lookup 充当mysql中的连接。

db.tempdate.aggregate([ 
    { $group : 
        { 
          _id : "$userId", 
          language : { $first: '$language' }, 
          status : { $first: '$status' },  
          desc : { $first: '$desc' } 
        } 
     },
     { $lookup: 
        { 
            from: "user", 
            localField: "_id", 
            foreignField: "user_id",
            as: "userData" 
         } 
     }
 ]).pretty();`

Output

`{
    "_id" : "5b891370f43fe3302bbd8001",
    "language" : "english",
    "status" : "A",
    "desc" : "Hi there - 3",
    "userData" : [
        {
            "_id" : ObjectId("5ba3633a12b8613823f3056e"),
            "user_id" : "5b891370f43fe3302bbd8001",
            "name" : "Bhuwan"
        }
    ]
}
{
    "_id" : "5b891370f43fe3302bbd8918",
    "language" : "english",
    "status" : "A",
    "desc" : "Hi there",
    "userData" : [
        {
            "_id" : ObjectId("5ba3634612b8613823f3056f"),
            "user_id" : "5b891370f43fe3302bbd8918",
            "name" : "Harry"
        }
    ]
}

答案 1 :(得分:1)

您可以将$group聚合阶段用于不同的userId,然后使用$lookup来获取用户数据。

db.col('posts').aggregate([
  { "$match": { "language": 'english', "status": "A" }},
  { "$sample": { "size": 10 }},
  { "$sort": { "_id": -1 }},
  { "$group": {
    "_id": "$userId",
    "language": { "$first": "$language" },
    "status": { "$first": "$status" },
    "desc": { "$first": "$desc" }
  }},
  { "$lookup": {
    "from": "users",
    "localField": "_id",
    "foreignField": "_id",
    "as": "ownerData"
  }}
])

答案 2 :(得分:1)

此外,您可以使用group$last

db.getCollection('posts').aggregate([
  { "$match": { "language": 'english', "status": "A" }},
  { "$group": {
    "_id": "$userId",
     "primaryId" : { "$last": "$_id" },
    "language": { "$last": "$language" },
    "status": { "$last": "$status" },
    "desc": { "$last": "$desc" }
  }},
  { "$lookup": {
    "from": "users",
    "localField": "_id",
    "foreignField": "_id",
    "as": "ownerData"
  }},
  { $unwind:{path: '$ownerData',preserveNullAndEmptyArrays: true} //to convert ownerData to json object
}
])