当前位置: 首页 > 知识库问答 >
问题:

如何使用lookup mongodb hapijs为集合中的每个文档从其他集合中提取文档数组

田琛
2023-03-14
companies: [
    {_id: "autogeneratedId", name: "companyname1"},
    {_id: "autogeneratedId", name: "companyname2"}
]
employees: [
    {_id: "autogeneratedId", salary: 10000, employeename: "employeename1", "company_id": "_id of company"}, 
    {_id: "autogeneratedId", salary: 50000, employeename: "employeename2", "company_id": "_id of company"}, 
    {_id: "autogeneratedId", salary: 25000, employeename: "employeename3", "company_id": "_id of company"}
]
products: [
    {_id: "autogeneratedId", price: 900, productname: "productname1", "company_id": "_id of company"}, 
    {_id: "autogeneratedId", price: 400, productname: "productname2", "company_id": "_id of company"}, 
    {_id: "autogeneratedId", price: 500, productname: "productname3", "company_id": "_id of company"}
]

我正在尝试从companies集合中提取公司列表。现在,除了companies列表之外,我还想根据companies集合的_id从集合productsemployees中获取每个对应公司的产品和员工列表。这是我正在尝试的代码

db.getCollection('companies').aggregate([
                {
                  $lookup:
                    {
                      from: "employees",
                      localField: "_id",
                      foreignField: "company_id",
                      as: "employees_array"
                    }
               },
                {
                  $lookup:
                    {
                      from: "products",
                      localField: "_id",
                      foreignField: "company_id",
                      as: "products_array"
                    }
               },
            ])

但是由于某种原因,上面的代码在products_array和employees_array中返回一个空数组。谁能告诉我,我在这里做错了什么?

同样,在employees_array和products_array中,我希望只获取基于条件的数据,例如employees having salary>=10000,products having price>=500。那么我该如何实现这一点呢?

共有1个答案

上官飞
2023-03-14

下面是我添加的文档:

公司

{
    "_id" : ObjectId("5a3455b69beb3178555e98da"),
    "name" : "companyname1"
}
{
    "_id" : ObjectId("5a3455b69beb3178555e98dc"),
    "name" : "companyname2"
}

雇员

{
    "_id" : ObjectId("5a34564c9beb3178555e990d"),
    "salary" : 10000,
    "employeename" : "employeename1",
    "company_id" : ObjectId("5a3455b69beb3178555e98da")
}
{
    "_id" : ObjectId("5a34564c9beb3178555e990f"),
    "salary" : 50000,
    "employeename" : "employeename2",
    "company_id" : ObjectId("5a3455b69beb3178555e98da")
}
{
    "_id" : ObjectId("5a34564c9beb3178555e9911"),
    "salary" : 25000,
    "employeename" : "employeename3",
    "company_id" : ObjectId("5a3455b69beb3178555e98dc")
}
{
    "_id" : ObjectId("5a3456929beb3178555e991e"),
    "price" : 900,
    "productname" : "productname1",
    "company_id" : ObjectId("5a3455b69beb3178555e98da")
}
{
    "_id" : ObjectId("5a3456929beb3178555e9920"),
    "price" : 400,
    "productname" : "productname2",
    "company_id" : ObjectId("5a3455b69beb3178555e98dc")
}
{
    "_id" : ObjectId("5a3456929beb3178555e9922"),
    "price" : 500,
    "productname" : "productname3",
    "company_id" : ObjectId("5a3455b69beb3178555e98da")
}
db.getCollection('companies').aggregate([{
        $lookup: {
            from: "employees",
            localField: "_id",
            foreignField: "company_id",
            as: "employees_array"
        }
    },
    {
        $lookup: {
            from: "products",
            localField: "_id",
            foreignField: "company_id",
            as: "products_array"
        }
    }
])
}
{
    "_id" : ObjectId("5a3455b69beb3178555e98da"),
    "name" : "companyname1",
    "employees_array" : [ 
        {
            "_id" : ObjectId("5a34564c9beb3178555e990d"),
            "salary" : 10000,
            "employeename" : "employeename1",
            "company_id" : ObjectId("5a3455b69beb3178555e98da")
        }, 
        {
            "_id" : ObjectId("5a34564c9beb3178555e990f"),
            "salary" : 50000,
            "employeename" : "employeename2",
            "company_id" : ObjectId("5a3455b69beb3178555e98da")
        }
    ],
    "products_array" : [ 
        {
            "_id" : ObjectId("5a3456929beb3178555e991e"),
            "price" : 900,
            "productname" : "productname1",
            "company_id" : ObjectId("5a3455b69beb3178555e98da")
        }, 
        {
            "_id" : ObjectId("5a3456929beb3178555e9922"),
            "price" : 500,
            "productname" : "productname3",
            "company_id" : ObjectId("5a3455b69beb3178555e98da")
        }
    ]
}
{
    "_id" : ObjectId("5a3455b69beb3178555e98dc"),
    "name" : "companyname2",
    "employees_array" : [ 
        {
            "_id" : ObjectId("5a34564c9beb3178555e9911"),
            "salary" : 25000,
            "employeename" : "employeename3",
            "company_id" : ObjectId("5a3455b69beb3178555e98dc")
        }
    ],
    "products_array" : [ 
        {
            "_id" : ObjectId("5a3456929beb3178555e9920"),
            "price" : 400,
            "productname" : "productname2",
            "company_id" : ObjectId("5a3455b69beb3178555e98dc")
        }
    ]
}
db.getCollection('companies').aggregate([{
        $lookup: {
            from: "employees",
            localField: "_id",
            foreignField: "company_id",
            as: "employees_array"
        }
    },
    {
        $lookup: {
            from: "products",
            localField: "_id",
            foreignField: "company_id",
            as: "products_array"
        }
    },
    {
        $project: {
            employees: {
                $map: {
                    input: {
                        "$filter": {
                            "input": "$employees_array",
                            "as": "employee",
                            "cond": {
                                "$gte": ["$$employee.salary", 10000]
                            }
                        }
                    },
                    as: "emp",
                    in: {
                        "salary": "$$emp.salary",
                        "name": "$$emp.employeename"
                        // You can add more fields
                    }
                }
            },
            products: {
                $map: {
                    input: {
                        "$filter": {
                            "input": "$products_array",
                            "as": "product",
                            "cond": {
                                "$gte": ["$$product.price", 500]
                            }
                        }
                    },
                    as: "prd",
                    in: {
                        "price": "$$prd.price",
                        "productname": "$$prd.productname"
                        // you can add more fields
                    }
                }
            }

        }
    }
])
 类似资料:
  • 所以我有一个帖子集。在“post”集合中,我有另一个名为“likes”的集合。 所以我想同时从每个文档中获取每个集合,并在之后映射它们。有没有办法做到这一点? 因为在Firebase中,您只能从一个文档中获取集合,但我想从每个文档中获取每个集合。

  • 如何使用JavaScript获取Firebase Firestore子集合“userPosts”中的所有文档?你可以在下面的图片中看到我的数据库结构。 以下是我尝试过的: 这段代码应该做的是获取子集合“userPosts”中的文档。它应该进入集合“posts”中的每个文档,然后进入“userPosts”并获取该子集合中的每个文档。 第一次收集“帖子” 子集合“userPosts”

  • 我正在为管理员创建一个与firebase集成的web应用程序,这个web应用程序被管理员用来监控用户从ionic开发的Android或iOS应用程序发布的帖子或评论。 我的问题是,是否可能获取特定用户评论的所有评论。我可以查询单个集合,但在本场景中,commentsDocument是一个子集合,我希望获取用户在所有post中的所有注释,以便进行监视。

  • 如何在Cloud Firestore中查询每个CollectionGroup的最新文档? 组中每个收藏中只有一个文档,最近的!

  • 我想从一个集合中得到所有的文件,然后用它们,得到他们的身份证。这里我的集合如何是用户集合,它只是一个集合和多个文档。我试了一下,但不起作用: 更新

  • 我想知道如何检索Firestore收藏中的所有其他文档。我有一个包含日期字段的文档集合。我想按日期对它们进行排序,然后从排序后的集合中的每个X大小的块中检索1个文档。我大约每10秒钟就添加一个新文档,并试图在前端显示历史数据,而不必下载这么多记录。