【问题标题】:how to fetch array of documents from other collections for each document in a collection using lookup mongodb hapijs如何使用查找mongodb hapijs从其他集合中为集合中的每个文档获取文档数组
【发布时间】:2018-05-30 03:27:36
【问题描述】:

我正在使用 MongoDB 和 HapiJs 我有 3 个 mongo db 集合如下:

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 从集合products 和employees 中获取每个相应公司的产品和员工列表。这是我正在尝试的代码

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 中,我只想获取基于员工薪水 >= 10000 和产品价格 >= 500 等条件的数据。那么我该如何实现呢?

【问题讨论】:

  • 您能否编辑您的帖子并为 _id 和 company_id 插入实际值?
  • 我的结构和值与 Alex P 的答案完全相同。预期结果也与 Alex P 在她的回答中描述的相同。但由于某种原因,我没有在products_array 和employees_array 中得到结果。 products 和 employees 中的 company_id 是对 companies 的 mongodb 自动生成的 _id 字段的引用。

标签: node.js mongodb lookup hapijs


【解决方案1】:

这是我添加的文件:

公司

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

如果你想要这些salary >= 10000 and products having price >= 500 条件,你必须像这样制定你的聚合管道:

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

        }
    }
])

如果某些数组不满足salary >= 10000(针对员工)或price >= 500(针对产品),您可能会得到 0 个结果,但这是正常的。

【讨论】:

  • 是的,我期待同样的结果,我正在获取公司列表,但在 products_array 和 employees_array 中得到 0 个结果。而且我还没有对products_array 和employees_array 数组的salary/price 设置任何条件,因为我想先在没有条件的情况下对其进行测试。
  • @DimpalSingh 你有什么结果吗?甚至来自一个集合?
  • 不,我什至没有从一个集合中得到什么
  • 好的,那么这是您的问题而不是查询。你如何连接到你的数据库?如果你直接在你的 mongo 上连接,那么这个查询应该不是问题
  • 我得到这样的东西:[{ "_id" : "5a3455b69beb3178555e98da", "name" : "companyname1", "employees_array" : [ ], }, { "_id" : "5a3455b69beb3178555e98dc", "name" : "companyname2", "employees_array" : [ ], }]
猜你喜欢
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-15
  • 2021-10-30
  • 2021-02-16
  • 2021-07-06
  • 1970-01-01
相关资源
最近更新 更多