【问题标题】:fetching mongodb collection records from multiple collections using nodejs使用nodejs从多个集合中获取mongodb集合记录
【发布时间】:2020-05-13 12:33:54
【问题描述】:

以下是全部说明 集合 1:用户

"_id" : ObjectId("5e2977e1cc1208c65c00648b"),
        "mappedShops" : [
                ObjectId("5e2976cbcc1208c65c006488"),
                ObjectId("5e2976cbcc1208c65c00690c"),
                ObjectId("5e2976cbcc1208c65c006499")
       "phoneNo" : 6789012345,
        "name" : "acdbcs",
        "address" : "address 2",
        "shopCode" : "D3137",
        "state" : "M.P",
        "city" : "Indore"

注意ma​​ppedShops 的详细信息 例如:ObjectId("5e2976cbcc1208c65c00690c") 在同一个用户集合中
集合 2:订单

"_id" : ObjectId("5e27f998a42d441fe8a8957f"),
        "isApproved" : false,
"orderCreatedOn" : ISODate("2020-01-22T18:30:00Z"),
"shopOrder" : [],
"frequency" : "WE",
"orderCreatedBy" : ObjectId("5e2976cbcc1208c65c00690c")

集合 3:付款

 "_id" :  ObjectId("5dd7900bcd00d33c245abbfa"),
 "paymentOfTheDay" : 400,
 "outstanding" : 100,
 "paymentDoneBy":ObjectId("5e2976cbcc1208c65c00690c")

场景是:我将从 req.body 获取 _id(即管理员 ID)这是我需要做的事情 1:我需要知道所有 mappedShops objectId,而不是所有那些 objectId,我需要找到所有这些 objectId 的详细信息 2:我需要查看该商店从订单集合中创建的订单。(对于所有这些 ID) 3:我需要查看收款中的未付款项(再次针对所有 ID) 这是我在提到的对象数组中需要发送到前端的内容 {"name","phoneNo","address"}(来自用户集合)+{"orderCreatedOn": ISODate("2020-01-22T18:30:00Z"),"isApproved"}(来自订单集合)+{"outstanding"}(来自收款) 预期响应可能如下所示:

"shopsListDetails":[{
"phoneNo","name","address","shopCode" ,"isApproved","outstanding"
}]

POSTMAN REQUEST这是管理员的ID

{
    "_id": "5e2977e1cc1208c65c00648b"
}

最终前端将收到我在 shopListDetails[{}] 中针对该管理员的用户集合中的所有 mappedShops 提到的所有数据 如果有人可以帮助我,我有点陷入困境

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    考虑到您共享的第一个架构是User

    我假设您将 order_id 存储在 payments Schemama 中

    你可以这样写聚合查询

        User.aggregate([
            {
                $match:{
                    _id:req.body.admin_id
                }
            },{
                $unwind:'$mappedShops'
            },{
                $lookup:{
                    from:'users',
                    localField:'mappedShops',
                    foreignField:'_',
                    as:'mappedShops'
                }
            },{
                $unwind:'$mappedShops'
            },{
                $lookup:{
                    from:'orders',
                    localField:'mappedShops._id',
                    foreignField:'orderCreatedBy',
                    as:'order'
                }
            },{
                $unwind:'$order'
            },{
                $lookup:{
                    from:'payments',
                    localField:'order._id',
                    foreignField:'order_id',
                    as:'payment'
                }
            },{
                $unwind:'$payment'
            },{
                $project:{
                    _id:0,
                    name:'$mappedShops.name',
                    phoneNo:'$mappedShops.phoneNo',
                    address:'$mappedShops.address',
                    orderCreatedOn:'$order.orderCreatedOn',
                    isApproved:'$order.isApproved',
                    outstanding:'$payment.outstanding'
                }
            }
        ])
    
    1. 首先,我们展开所有 mappedShops 并从 Lookups 中获取相同的单个对象 |这为我们提供了最终数据的用户详细信息
    2. 然后,我们从orders集合中找到每个mappedshops的匹配顺序$lookup$unwind相同 |这为我们提供了最终数据的订单详细信息
    3. 最后,我们通过$lookup匹配order_id内部收款并获取每个订单的付款状态 |这为我们提供了最终数据的付款状态

    PS : 对于这个给工人,你必须在orderspayments 集合中都有每个订单的条目,无论付款是否完成

    如果您需要更多说明/此处需要任何更改,请在下方评论

    【讨论】:

    • 不,收款中没有order_id,但收款中有shop_id,可以在这种情况下使用@Sarfraaz
    • 不是很神的做法,你需要将特定order的id存储在收款里面,因为同一个shop_id会有多个orders,所以你不知道是哪个@ 987654336@ 是哪个order
    • 你是绝对正确的,但实际上有一点后台订单需要在午夜(chron 工作)的 shopid 上创建那个特定日期只有一个订单 ID,这就是我们有 shopid 的收款原因,你可以理解业务需求:-) 不能做太多@Sarfraaz
    • 在这种情况下,您需要将日期存储在订单和收款中,以便我们可以匹配该日期以查找特定订单的付款,这不是最佳解决方案,但这适用于您的案例
    • 好的,让我试试看,如果我需要更多说明,请回复
    【解决方案2】:

    请试试这个:

    db.users.aggregate([
        {
            $match: {
                _id: req.body.adminID
            }
        }, {
            $lookup: {
                from: 'users',
                localField: 'mappedShops',
                foreignField: '_id',
                as: 'mappedShops'
            }
        }, { $unwind: '$mappedShops'}, { $replaceRoot: { newRoot: "$mappedShops" } },
        { 
           $lookup:
            {
                from: "orders",
                let: { mappedShopsId: "$_id" },
                pipeline: [
                    {
                        $match: { $expr: { $eq: ["$orderCreatedBy", "$$mappedShopsId"] } }
                    },
                    { $project: { orderCreatedOn: 1, isApproved: 1 } }
                ],
                as: "orders"
            }
        },{
           $lookup:
            {
                from: "payments",
                let: { mappedShopsId: "$_id" },
                pipeline: [
                    {
                        $match: { $expr: { $eq: ["$paymentDoneBy", "$$mappedShopsId"] } }
                    },
                    { $project: { outstanding: 1 } }
                ],
                as: "payments"
            }
        },
        { $project: { name: 1, phoneNo: 1, address: 1, shopCode: 1, orders: 1, payments: 1 } }
    ])
    

    测试: MongoDB-Playground

    【讨论】:

    • db.users.aggregate([ { $match: { _id: ObjectId("5e2977e1cc1208c65c00648b") } }, { $lookup: { from: 'users', localField: 'mappedShops', foreignField: '_id', as: 'mappedShops'........这个foreignField: '_id', 代表用户集合本身的“_id”字段对吧?@srinivasy
    • @sachin.pandey :是的,正确,尝试该查询并让我知道!在第一个 $match 中,将 _id: ObjectId("5e2977e1cc1208c65c00648b") 替换为 _id:req.body.adminID,结果我将订单和付款保留为数组,因为如果您的 mappedShops 在订单和付款中可能有多个匹配(这很常见)那么它很容易作为数组来区分 & 最好表示!!
    • 是的,您的查询在 shell 中运行,但在 nodejs 中不运行,我在 nodejs 中的代码几乎与您的查询相同,除了 exports.vendorWiseIndent = async (req, res, next) => { const { adminId } = req.body try { const shopListDetails= await User.aggregate([{ $match: { _id: adminId } }..."rest 是您的查询与"....return res.status(200).json( { shopsListDetails }); } catch (error) { res.send(error); } } POSTMAN RESPONSE: { "shopsListDetails": [] }@ srinivasy
    • 是的 db 是对的 .. 如果我发布这个问题会更好,我会将链接粘贴到 cmets 请看一下
    • 是的@srinivasy 我后来能够解决这个问题.. 感谢您的帮助解决了我的问题
    猜你喜欢
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    相关资源
    最近更新 更多