【问题标题】:How to lookup in another collection with objectID of main collection in mongodb如何在mongodb中使用主集合的objectID在另一个集合中查找
【发布时间】:2021-08-25 11:56:36
【问题描述】:

我正在尝试通过查找从另一个集合中获取数据

集合“用户”

{
    "_id":{
        "$oid":"60bf4bb31f45d98903d1851f"
    },
    "name":"Dave",
    "center":"THGJ556",


}

集合“地址”

{
    "_id":{
        "$oid":"60bf4bb31f45d98903d1851f"
    },
    "userId":"60bf4bb31f45d98903d1851f",    
}

集合“应用程序”

{
    "_id":{
        "$oid":"60bf4bb31f45d98903d1851f"
    },
    "userId":"60bf4bb31f45d98903d1851f",
    "centerId":"THGJ556",   

},
{
    "_id":{
        "$oid":"60bf4bb31f45d98903d3647j"
    },
    "userId":"60bf4bb31f45d98903d1851f",
    "centerId":"JHGJ5476",  

}

现在我需要所有表中的数据。

这是我的代码:

users.aggregate([
        
        {
          $lookup: {
            from: "addresses",
            localField: "_id",
            foreignField: "userId",
            as: "addressData"
          }
        },

        {
          $lookup: {
            from: "applications",
            pipeline: [
              { $match: 
                { userId:"$_id", centerId: "JHGJ5476"} 
              },
           ],
           as: "applicationData"
          }
        },
        
      ] ,function(err,  result) {
        
        if (err) {
          console.log(err)
          
        } else {
          console.log(result)
        }        
      });

我在管道中使用聚合和匹配时做错了。

我正确获取了 addressData,但我在 applicationData 中什么也没得到 [],因为我怀疑 userId:"$_id" 有问题

【问题讨论】:

    标签: node.js typescript mongodb mongoose


    【解决方案1】:

    正如docs 解释:

    $match 阶段需要使用 $expr 运算符来访问变量。 $expr 允许在 $match 语法中使用聚合表达式。

    所以你必须使用$expr 进入$match 阶段和let 阶段。

    • let 阶段是定义要使用的变量到$exprid: $_id
    • $expr$and$eq 一起使用是同时获得这两个条件。
    db.users.aggregate([
      {
        $lookup: {
          from: "addresses",
          localField: "_id",
          foreignField: "userId",
          as: "addressData"
        }
      },
      {
        $lookup: {
          from: "applications",
          let: {"id": "$_id"},
          pipeline: [
            {
              $match: {
                "$expr": {
                  "$and": [
                    {"$eq": ["$userId","$$id"]},
                    {"$eq": ["$centerId","JHGJ5476"]}
                  ]
                }
              }
            }
          ],
          as: "applicationData"
        }
      }
    ])
    

    查看this 示例。

    【讨论】:

    • 谢谢,我尝试了上述解决方案,但它只能通过将 userId 转换为 objectId 来工作,有什么具体原因吗? {"$eq": [ { "$toObjectId": "$userId" }, "$$id"]},
    • 也许查询将_id 作为字符串并与ObjectId 比较返回false。使用 mongoose,我曾经使用返回新 ObjectId 的方法:function generateObjectId(id) { return Types.ObjectId(id) }。然后你可以在查询中使用这个方法而不是使用$toObjectId。但是都一样,就是比较 ObjectId vs ObjectId 而不是 String vs ObjectId。
    猜你喜欢
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2021-12-31
    • 1970-01-01
    • 2012-10-15
    • 2019-08-07
    相关资源
    最近更新 更多