mongodb 左联结写法

这篇教程探讨如何在MongoDB中使用aggregate函数模拟SQL的左联结操作,涉及$match、$unwind、$project等函数的用法,并通过实例展示了不同类型的左联结查询,包括基础左联结、带where条件的左联结以及带有联结条件的左联结。由于MongoDB不直接支持左联结,文章通过$redact函数的$PRUNE特性来实现类似效果。

sql to mongoDB mapping chart 一些比较简单的官方文档例子,已经有的就不再写例子
https://docs.mongodb.com/manual/reference/sql-comparison/

本教程主要是讲aggregate的一些函数实现左联结的用法,用到的函数有
$match,$unwind,$project,$let,$cond,$redact等

准备测试数据

Oracle数据库 初始数据,address/custInfo表:

custInfo

_idnameameagegender
1001sum20F
1002stone21M
1003kral22M
1004git22M

address

_idstatuscustIdregionhomeAdd
1A1001GuangZhou天河北路
2A1001ShangHai天河南路
3A1002BeiJing天安门
4B1002沙河路17号
5B1004GuangZhou沙河路18号

Mongo数据库 表结构 (假设数据和oracle数据库的数据一样)
custInfo

{
    _id:"1001",
    name:"sum",
    age:20,
    gender:"F",
    address:[
        {
            status:"A",
            region:"GuangZhou",
            homeAdd:"天河北路"
        },
        {
            status:"A",
            region:"ShangHai",
            homeAdd:"天河南路"
        }
    ]
}

练习一:左联结

sql

    select cu._id as custId,cu.name,ad.region,ad.homeAdd,ad.status 
    from custInfo cu
    left join address ad on cu._id=ad.custId;

mongoQuery

db.custInfo.aggregate([
    {$unwind:{
        path:"$address",
        preserveNullAndEmptyArrays:true}
    },
    {$project:{
        _id:1,
        name:1,
        region:"$address.region",
        homeAdd:"$address.homeAdd",
        status:"$address.status"
        }
    }
]);

查询结果

custIdnameregionhomeAddstatus
1001sumGuangZhou天河北路A
1001sumShangHai天河南路A
1002stoneBeiJing天安门A
1002stone沙河路17号B
1003kral
1004gitGuangZhou沙河路17号B

练习二:左联结+where条件

sql

    select cu._id as custId,cu.name,ad.region,ad.homeAdd,ad.status from custInfo cu
    left join address ad on cu._id=ad.custId
    where ad.status='A';

mongoQuery

db.custInfo.aggregate([
    {$unwind:{
        path:"$address",
        preserveNullAndEmptyArrays:true}
    },
    {$match:{"address.status":"A"}},
    {$project:{
        _id:1,
        name:1,
        region:"$address.region",
        homeAdd:"$address.homeAdd",
        status:"$address.status"
        }
    }
]);

查询结果

custIdnameregionhomeAddstatus
1001sumGuangZhou天河北路A
1001sumShangHai天河南路A
1002stoneBeiJing天安门A

练习三:左联结+联结条件

sql

    select cu._id as custId,cu.name,ad.region,ad.homeAdd,ad.status 
    from custInfo cu
    left join address ad on cu._id=ad.custId and ad.status='A';

mongoQuery

db.custInfo.aggregate([
    {$unwind:{
        path:"$address",
        preserveNullAndEmptyArrays:true}
    },
    {$project:{
        _id:1,
        name:1,
        items:"$address",
        acStatus:{
            $let:{
                vars:{},
                in:{
                    $cond:{
                        if:{$eq:["$address.status","A"]},
                        then:"$address.status",
                        else:"delete"
                    }
                      }
                  }
            }
        }
    },
    {$group:{
        _id:{
            _id:"$_id",
            name:"$name",
            gender:"$gender",
            },
        itemsSold:{
            $push:{
                status:"$items.status",
                region:"$items.region",
                homeAdd:"$items.homeAdd",
                deleteflag:"$acStatus"
                }
            }

        }
    },
    {
        $redact: {
            $cond: {
                if: {$eq:["$deleteflag","delete"]
                },
                then: "$$PRUNE",
                else: "$$DESCEND"
            }
        }
    },
    {$unwind:{
        path:"$itemsSold",
        preserveNullAndEmptyArrays:true}
    },
    {$project:{
        _id:0,
        custId:"$_id._id",
        name:"$_id.name",
        region:"$itemsSold.region",
        homeAdd:"$itemsSold.homeAdd",
        status:"$itemsSold.status"
        }
    },
    {$sort:{"custId":1}}
]);

查询结果

custIdnameregionhomeAddstatus
1001sumGuangZhou天河北路A
1001sumShangHai天河南路A
1002stoneBeiJing天安门A
1003karl
1004git

在这里说明一下,mongodb 不支持左联结,所以的使用其他思路去解决这个问题。简单总结一下就是通过$redact函数的$PRUNE清除数据的功能,这里需要具体讲一下$redact函数的用法,下回分解

created Date 2017年5月29日 19:24:26

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值