MongoDB Find All Matching数组,返回所有不仅仅是唯一的

时间:2018-03-21 22:17:59

标签: node.js mongodb aggregation-framework

我有一个用户集合。在该集合中,每个用户在输入奖品时将在其个人资料中存储奖品ID。导出典型的用户文档

{ 
    "_id" : ObjectId("5aacff47c67f99103bcbf693"), 
    "firstName" : "Test", 
    "lastName" : "Test", 
    "password" : "$2a$10$mJjzPFWuYPmK8A07nc284O8g9SStFpuaVzfyWOZgaCmVaomIxk5qO", 
    "email" : "test1@test.com", 
    "points" : NumberInt(6), 
    "prizes" : [
        ObjectId("5aafd1673a5b2cb294b69620"), 
        ObjectId("5aafd1673a5b2cb294b69620"), 
        ObjectId("5aafd1673a5b2cb294b69620"), 
        ObjectId("5aafd1673a5b2cb294b69620"), 
        ObjectId("5aafd1673a5b2cb294b69620"), 
        ObjectId("5ab28ca784aa6390aa5a1dba")
    ], 
    "messages" : [

    ], 
    "__v" : NumberInt(26)
}

我写了一个api电话,当用户登陆他们的帐户页面时,它会找到用户并返回他们的奖品(奖品阵列)。然后,我想使用这些查询数据库来查找每个条目的标题/内容,以便它可以显示在前端。

我已经完成了这两种方式

var prizes = user.prizes

       //mongo

       ids = prizes.map(function(el) { return mongoose.Types.ObjectId(el) })

       Prize.aggregate([
        { $match: { "_id": { "$in": ids } } }

      ], function(err, ret){
        if (err) {
            return res.status(500).json({
                title: 'An error occurred',
                error: err
            });

        }
          console.log(ret)
      }
    )

Prize.find( { _id: prizes }, { title: 1, content: 1 }, function(err, ret){
        if (err) {
            return res.status(500).json({
                title: 'An error occurred',
                error: err
            });

        }
console.log(ret)



       })

现在困难的部分,这两个操作只返回唯一的文件,(2)而不是我想要的6个。

我想查找每个条目ID,然后返回该奖项ID的标题和内容,无需关心是否唯一或有响应的计数,因此将我的用户提供给它将返回

{1x独特的医生数量4} {1x unique doc,count 1}

或返回6个回复。

即使我使用.count(),它也只计算2.我知道我必须以错误的方式解决这个问题,因为mongo是正确的,因为我要求它找到符合id的文件我通过它和它找到2个匹配的id并为它们提供服务。

我是否通过要求它做一些不同的事情来破坏它的功能?其他选择?将其包含在每个节点中并手动查询每个id并推送到数组?

1 个答案:

答案 0 :(得分:0)

  

获取特定用户的奖品。

$unwind$group不计入奖品,然后$lookup来获取3.4中的奖品字段。

User.aggregate([
  {"$match":{"_id":mongoose.Types.ObjectId(userid)}},
  {"$unwind":"$prizes"},
  {"$group":{"_id":"$prizes","count":{"$sum":1}}},
  {"$lookup":{
    "from":"prizes", // name of the prize collection
    "localField":"_id", 
    "foreignField":"_id",
    "as":"prizes"
  }},
  {"$addFields":{"prizes":{"$arrayElemAt":["$prizes",0]}}}
])
  

获取用户和奖品。

使用$lookup后跟$map来保持字段不被查找,并使用$filter$size来计算3.4中每个ID的奖励数。

这样的东西
User.aggregate([
  {"$match":{"_id":mongoose.Types.ObjectId(userid)}},
  {"$lookup":{
    "from":"prizes", // name of the prize collection
    "localField":"prizes",
    "foreignField":"_id",
    "as":"prizeinfo"
  }},
  {"$addFields":{
    "prizeinfo":{
      "$map":{
        "input":"$prizeinfo",
        "as":"pi",
        "in":{
          "title":"$$pi.title",
          "content":"$$pi.content",
          "count":{
            "$size":{
              "$filter":{
                "input":"$prizes",
                "as":"p",
                "cond":{"$eq":["$$pi._id","$$p"]}
              }
            }
          }
        }
      }
    }
  }}
])