在 mongoose 中使用查找填充一个集合

Posted

技术标签:

【中文标题】在 mongoose 中使用查找填充一个集合【英文标题】:Populate one collection with lookup in mongoose 【发布时间】:2020-09-10 15:57:42 【问题描述】:

我正在尝试使用查找来填充集合。问题是我需要在 express js 中使用猫鼬一次加入三个集合。 我有三个集合,即用户、技能、用户技能

User 和 UserSkills 已连接。技能和用户技能是相互关联的。但不是用户和技能。

我的模型是这样的

用户

 
    _id: 5ec6d940b98e8f2c3cea5f22, 
    name: "test one", 
    email: "test@example.com" 

技能

 
    _id: 5ec786b21cea7d8c8c186a54, 
    title: "java" 

用户技能


    _id: 5ec7879c1cea7d8c8c186a56,
    skillId: "5ec786b21cea7d8c8c186a54",
    userId: "5ec6d940b98e8f2c3cea5f22", 
    level: "good" 

我试过了

user = await User.aggregate([
        $lookup: 
          from: "userskills",
          localField: "_id",
          foreignField: "userId",
          as: "userskills"
        
      , 
        $unwind: 
          path: "$userskills",
          preserveNullAndEmptyArrays: true
        
      , 
        $lookup: 
          from: "skills",
          localField: "userskills.skillId",
          foreignField: "_id",
          as: "userskills.skill",
        
      , 
        $group: 
          _id : "$_id",
          name:  $first: "$name" ,
          skill:  $push: "$skills" 
        
      , 
        $project: 
          _id: 1,
          name: 1,
          skills: 
            $filter:  input: "$skills", as: "a", cond:  $ifNull: ["$$a._id", false]  
           
        
      ]);

要求的结果:


    "users" : [
        
            _id: "5ec6d940b98e8f2c3cea5f22"
            name: "test one",
            email: "testone@example.com",
            "skills" : [
                
                    _id: "5ec7879c1cea7d8c8c186a56",
                    level: "good",
                    "skill" : 
                         _id: "5ec786b21cea7d8c8c186a54",
                         title: "java"
                    
                
           ]
        ,
        
            _id: "5ec6d940b98e8f2c3cea5f23"
            name: "test two",
            email: "testtwo@example.com",
            "skills" : [
                
                    _id: "5ec7879c1cea7d8c8c186a57",
                    level: "good",
                    "skill" : 
                         _id: "5ec786b21cea7d8c8c186a55",
                         title: "php"
                    
                
           ]
        
    ]

使用时

user = await User.find().populate('Skills").exec()

结果来了


    "users" : [
        
            _id: "5ec6d940b98e8f2c3cea5f22"
            name: "test one",
            email: "testone@example.com",
            "skills" : [
                
                    _id: "5ec7879c1cea7d8c8c186a56",
                    level: "good",
                    skillId: "5ec786b21cea7d8c8c186a55" 
                
           ]
        
    ]

问题是我还需要获取技能名称。请帮我解决这个问题。我正在 nodejs 和 mongodb 中编写后端 API。

【问题讨论】:

【参考方案1】:

您可以将第二个$lookup 作为custom pipeline 的一部分嵌入:

await User.aggregate([
    
        $lookup: 
            from: "userskills",
            let:  user_id: "$_id" ,
            pipeline: [
                 $match:  $expr:  $eq: [ "$$user_id", "$userId" ]   ,
                
                    $lookup: 
                        from: "skills",
                        localField: "skillId",
                        foreignField: "_id",
                        as: "skill"
                    
                ,
                 $unwind: "$skill" 
            ],
            as: "skills"
        
    
])

Mongo Playground

【讨论】:

嗨,这返回了一个空的技能数组 @LijomonCJohn 您可以将您的数据与 mongo 游乐场示例进行比较吗? 在 Mongo Playground 中,它来了,我需要的结果,但是当我在 node 或 mongo 命令行中运行时。技能集以 [](空数组)的形式出现 [mongo Playground] (mongoplayground.net/p/e9SXEgDa83b) 我需要测试的实际数据。 @LijomonCJohn from 中的值必须是集合的物理名称。 from: "userskills"真的是你的实体收藏名称userskills吗?

以上是关于在 mongoose 中使用查找填充一个集合的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Mongoose 在 mongoDB 中填充 3 个集合

Mongoose 只查找那些在另一个集合中有条目的人

使用 Mongoose 查找和计数集合元素

集合未保存在 mongodb 中(来自 mongoose 填充文档的故事集合)

Mongoose 先填充,然后根据填充的字段进行过滤

Mongoose 先填充,然后根据填充的字段进行过滤