MongoDB在另一个集合中的Field中查找文档

发布于 2025-01-23 19:04:40 字数 1955 浏览 0 评论 0原文

我有两个收藏:共享和材料。

共享:

{
 from_id: 2
 to_id: 1
 material_id: material1
}

材料:

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

- edit: 有三种材料,2个属于组织_id(1),而1个属于组织_id(2)。 anchancy_id在材料1中不匹配1(而不是属于材料2),但是在共享集合中,to_id确实匹配1。如果存在匹配,我想找到与材料_id等于材料的材料文档_id共享并查找组织_id等于1的材料文档。

我想检查共享字段(to_id)是否具有等于材料(anchancy_id)字段的值,并检查agristancon_id是否等于1 。总数。

如果没有同等值,我想省略该结果,并以仅等于1的组织_ID发送对象,并获得此结果的总数。

现在,我以.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
}
]

I have two collections: Sharing and Material.

Sharing:

{
 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
},

--Edit:
There are three materials, 2 belong to organization_id(1) and 1 belongs to organization_id(2). The organization_id does not match 1 in material1 (and instead belongs to material2), but in the Sharing collection, the to_id does match 1. If the match exists, I'd like to find the Material document _id which is equal to the material_id of Sharing AND find the Material documents where the organization_id is equal to 1.

I'd like to check if a field in Sharing (to_id) has a value that is equal to a field in Material (organization_id) AND check if organization_id is equal to 1. If there is a document that exists from this, do another check to find whether the _id of Material is equal to the material_id of Sharing and return all documents & the total count.

If there is no equal value, I'd like to omit that result and send the object with only organization_id equal to 1 and get the total count of this result.

Right now, I do it in a very inefficient way using .map() to find this. Below is my code:

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 });       
    }
}

I have tried using aggregation to get my desired result but I cannot find any solution that fits my requirements. Any help would be great as I am quite new to using mongodb. Thanks.

Edit (desired result):

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我纯我任性 2025-01-30 19:04:40

您可以在$查找中使用子围栏来执行过滤。 $ 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 供您参考。

You can use sub-pipeline in a $lookup to perform the filtering. $addFields the count using $size later.

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"
      }
    }
  }
])

Here is the Mongo playground for your reference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文