mongodb如何使用聚集等填充

时间:2019-12-28 16:53:50

标签: mongodb mongoose nosql

该代码示例位于 Mongo Playground

  

https://mongoplayground.net/p/W4Qt4oX0ZRP

假设以下文件

[
  {
    _id: "5df1e6f75de2b22f8e6c30e8",
    user: {
      name: "Tom",
      sex: 1,
      age: 23
    },
    dream: [
      {
        label: "engineer",
        industry: "5e06b16fb0670d7538222909",
        type: "5e06b16fb0670d7538222951",

      },
      {
        label: "programmer",
        industry: "5e06b16fb0670d7538222909",
        type: "5e06b16fb0670d7538222951",

      }
    ],
    works: [
      {
        name: "any engineer",
        company: "5dd7fd51b0ae1837a08d00c8",
        skill: [
          "5dc3998e2cf66bad16efd61b",
          "5dc3998e2cf66bad16efd61e"
        ],

      },
      {
        name: "any programmer",
        company: "5dd7fd9db0ae1837a08d00e2",
        skill: [
          "5dd509e05de2b22f8e67e1b7",
          "5dd509e05de2b22f8e67e1bb"
        ],

      }
    ]
  }
]

我尝试使用aggregate $lookup $unwind

db.coll.aggregate([
  {
    $unwind: {
      path: "$dream",

    }
  },
  {
    $lookup: {
      from: "industry",
      localField: "dream.industry",
      foreignField: "_id",
      as: "dream.industry"
    },

  },
  {
    $unwind: {
      path: "$dream.industry",

    }
  },
  {
    $lookup: {
      from: "type",
      localField: "dream.type",
      foreignField: "_id",
      as: "dream.type"
    },

  },
  {
    $unwind: {
      path: "$dream.type",

    }
  },
  {
    $unwind: {
      path: "$works",

    }
  },
  {
    $lookup: {
      from: "company",
      localField: "works.company",
      foreignField: "_id",
      as: "works.company"
    },

  },
  {
    $unwind: {
      path: "$works.company",

    }
  },
  {
    $lookup: {
      from: "skill",
      localField: "works.skill",
      foreignField: "_id",
      as: "works.skill"
    },

  },

])

执行上面的代码没有得到想要的结果!

这就是我的期望

{
  _id: "5df1e6f75de2b22f8e6c30e8",
  user: {
    name: 'Tom',
    sex: 1,
    age: 23
  },
  dream: [
    {
      label: 'engineer',
      industry: {
        _id: "5e06b16fb0670d7538222909",           // Industry doc _id
        name: 'IT',
        createdAt: "2019-12-28T01:35:44.070Z",
        updatedAt: "2019-12-28T01:35:44.070Z"
      },
      type: {
        _id: "5e06b16fb0670d7538222951",           // Type doc _id
        name: 'job',
        createdAt: "2019-12-28T01:35:44.070Z",
        updatedAt: "2019-12-28T01:35:44.070Z"
      },
    },
    {
      label: 'programmer',
      industry: {
        _id: "5e06b16fb0670d7538222909",           // Industry doc _id
        name: 'IT',
        createdAt: "2019-12-28T01:35:44.070Z",
        updatedAt: "2019-12-28T01:35:44.070Z"
      },
      type: {
        _id: "5e06b16fb0670d7538222951",           // Type doc _id
        name: 'job',
        createdAt: "2019-12-28T01:35:44.070Z",
        updatedAt: "2019-12-28T01:35:44.070Z"
      }
    }
  ],
  works: [
    {
      name: 'any engineer',
      company: {
        _id: "5dd7fd51b0ae1837a08d00c8",          // Company doc _id
        name: 'alibaba',
        area: 'CN',
      },
      skill: [
        { 
          _id: "5dc3998e2cf66bad16efd61b",        // Skill doc _id
          name: 'Java' 
        }, 
        { 
          _id: "5dc3998e2cf66bad16efd61e",        // Skill doc _id
          name: 'Php' 
        }, 
      ]
    },
    {
      name: 'any programmer',
      company: {
        _id: "5dd7fd9db0ae1837a08d00e2",           // Company doc _id
        name: 'microsoft',
        area: 'EN',
      },
      skill: [
        { 
          _id: "5dd509e05de2b22f8e67e1b7",           // Skill doc _id
          name: 'Golang' 
        },
        { 
          _id: "5dd509e05de2b22f8e67e1bb",         // Skill doc _id
          name: 'Node.js'
        }
      ]
    },
  ]
}

预期结果是dream是一个数组,works是一个数组,并且dream.industry从ObjectId更改为文档,dream.type从ObjectId更改为文档,{{ 1}}从ObjectId更改为文档

使用填充时,我可以轻松完成

works.company

我参考了以下问题

  
      
  1. mongoose aggregate lookup array(与我的问题几乎相同,但尚未解决)
  2.   
  3. $lookup on ObjectId's in an array
  4.   

希望得到大家的帮助,谢谢!

1 个答案:

答案 0 :(得分:0)

为了简化操作,我不会更改当前管道,而只是在其末尾添加一个$group阶段以重新构造数据。

{
    $group: {
        _id: "$_id",
        user: {$first: "$user"},
        dream: {$addToSet: "$dream"},
        works: {$addToSet: "$works"}
    }
}

话虽如此,如果您使用的是Mongo 3.6+版本,我建议您使用$lookup的“较新版本”来重新编写管道,从而避免所有这些{{1} }。