Mongodb 从另一个 collection 中的字段中找到 collection 中的文档

Mongodb find document in collection from field in another collection

我有两个 collection:共享和 Material。

分享:

{
 from_id: 2
 to_id: 1
 material_id: material1
}

Material:

{
 _id: material1
 organization_id: 2
},
{
 _id: material2
 organization_id: 1
},
{
 _id: material3
 organization_id: 1
},

--编辑: 有3个素材,2个属于organization_id(1),1个属于organization_id(2)。 organization_id 不匹配 material1 中的 1(而是属于 material2),但在共享 collection 中,to_id 匹配 1。如果匹配存在,我想找到等于 material_id 共享的 Material 文档 _id 并找到 organization_id 等于 1 的 Material 文档。

我想检查共享 (to_id) 中的字段是否具有等于 Material (organization_id) 中的字段的值,并检查 organization_id等于1,如果有文档从这里存在,再检查一下Material的_id是否等于Sharing的material_id和returnall文件和总数。

如果没有相等的值,我想省略那个结果并发送 object 只有 organization_id 等于 1 并得到这个结果的总数。

现在,我使用 .map() 以一种非常低效的方式来查找它。下面是我的代码:

export const getMaterials = async (req, res) => {
    const sharing = await Sharing.find({to_id: 1});
    let doneLoad;

    try {
        if (sharing && sharing.length>0) {
            const sharingTotal = await Material.find( {$or: [ {organization_id: 1}, {_id: sharing.map((item) => item.material_id)} ] } ).countDocuments();
            const sharingMats = await Material.find( {$or: [ {organization_id: 1}, {_id: sharing.map((item) => item.material_id)} ] } );
            res.status(200).json({data: sharingMats});
            doneLoad= true;
        }
        else if (!doneLoad) {
            const materialTotal = await Material.find({organization_id: 1}).countDocuments();
            const materials = await Material.find({organization_id: 1});
            res.status(200).json({data: materials});
        }
    } catch (error) {
        res.status(404).json({ message: error.message });       
    }
}

我曾尝试使用聚合来获得我想要的结果,但我找不到任何符合我要求的解决方案。任何帮助都会很棒,因为我对使用 mongodb 还很陌生。谢谢。

编辑(期望的结果):

Materials: [
{
 _id: material1,
 organization_id: 1
},
{
 _id: material2,
 organization_id: 1
},
{
 _id: material3,
 organization_id: 1
}
]

您可以在 $lookup 中使用 sub-pipeline 来执行过滤。 $addFields 稍后使用 $size 计数。

db.Sharing.aggregate([
  {
    "$match": {
      to_id: 1
    }
  },
  {
    "$lookup": {
      "from": "Material",
      "let": {
        to_id: "$to_id",
        material_id: "$material_id"
      },
      "pipeline": [
        {
          "$match": {
            $expr: {
              $or: [
                {
                  $eq: [
                    "$$to_id",
                    "$organization_id"
                  ]
                },
                {
                  $eq: [
                    "$$material_id",
                    "$_id"
                  ]
                }
              ]
            }
          }
        },
        {
          "$addFields": {
            "organization_id": 1
          }
        }
      ],
      "as": "materialLookup"
    }
  },
  {
    "$addFields": {
      "materialCount": {
        $size: "$materialLookup"
      }
    }
  }
])

这里是Mongo playground供您参考。