首页 > 解决方案 > 如何在 mongoDb 中加入多个集合

问题描述

我想在 MongoDB 中加入两个以上的集合。可以加入吗。。

在这里,我有三个集合:

员工服务:

[
    {
      "_id": ObjectId("A"),
      "service_id": "Service-a"
      "staffs": [
        {
          "id": ObjectId("STAFF-A")
        }
      ],
      
    },
    {
      "_id": ObjectId("B"),
      "service_id": "Service-b"
      "staffs": [
        {
          "id": ObjectId("STAFF-A")
        }
      ],
      
    },
  ]

服务 :

[
    {
      "_id": "Service-a",
      "name": "Services 1",
      "service_category_id": "CAT-a"
    },
    {
      "_id": "Service-b",
     "name": "Services 2",
      "service_category_id": "CAT-b"
    },
  ]

服务类别

[
    {
      "_id": ObjectId("CAT-a"),
      "name": "cat 1",
      
    },
    {
      "_id": ObjectId("CAT-b"),
      "name": "cat 2",
    }
  ]

我希望根据分配给特定员工的服务类别来获取所有服务。这里有两个服务,例如service-a and service-b assigned to staff-a.

我尝试过以下方法。

db.staff_services.aggregate([
  {
    "$match": {
      "staffs.id": ObjectId("STAFF-A")
    }
  },
  {
    $lookup: {
      from: "service",
      localField: "service_id",
      foreignField: "_id",
      as: "services"
    }
  },
  {
    $lookup: {
      from: "service_category",
      localField: "services.service_category_id",
      foreignField: "_id",
      as: "category"
    }
  },
  {
    "$addFields": {
      "category": {
        "$map": {
          "input": "$category",
          "as": "cat",
          "in": {
            _id: "$$cat._id",
            name: "$$cat.name",
            is_featured: "$$cat.is_featured",
            is_active: "$$cat.is_active",
            services: {
              "$filter": {
                "input": "$services",
                "as": "ser",
                "cond": {
                  "$eq": [
                    "$$cat._id",
                    "$$ser.service_category_id"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  
])

预期输出:

{
 staff_id:"STAFF-A",
 category:[
   {
     id: "CAT-a",
     name: "Cat 1",
     services:[
       {
         id:"service-a",
         name:"service 1"
       }
      ]
    },
    {
     id: "CAT-b",
     name: "Cat 2",
     services:[
       {
         id:"service-b",
         name:"service 2"
       }
      ]
  }
  ]
}

标签: node.jsmongodbmongoosemongodb-query

解决方案


有趣的问题让我有点挣扎,但以下应该有效:

首先你match按给定staffId,然后group按这个 id 并收集所有serviceIds。之后,您对服务/类别进行两次查找,最后查找map所需的结构:

db.staff_services.aggregate([
  {
    $match: {
      "staffs.id": "STAFF-A"
    }
  },
  {
    "$group": {
      _id: "$staffs.id",
      serviceIds: {
        "$addToSet": "$service_id"
      }
    }
  },
  {
    $lookup: {
      from: "services",
      localField: "serviceIds",
      foreignField: "_id",
      as: "servicesTmp"
    }
  },
  {
    $lookup: {
      from: "service_categories",
      localField: "servicesTmp.service_category_id",
      foreignField: "_id",
      as: "categoriesTmp"
    }
  },
  {
    $addFields: {
      category: {
        $map: {
          input: "$categoriesTmp",
          in: {
            id: "$$this._id",
            name: "$$this.name",
            services: {
              $arrayElemAt: [
                "$servicesTmp",
                {
                  "$indexOfArray": [
                    "$servicesTmp.service_category_id",
                    "$$this._id"
                  ]
                }
              ]
            },
            
          }
        }
      }
    }
  },
  {
    "$project": {
      categoriesTmp: 0,
      serviceIds: 0,
      servicesTmp: 0,
      "category.services.service_category_id": 0
    }
  }
])

这是关于 mongoplayground 的示例:https ://mongoplayground.net/p/QdDpvJCLTtC


推荐阅读