MongoDB中的多表关联查询($lookup)将ObjectID转换为String

$lookup的功能及语法

是将每个输入待处理的文档,经过$lookup 阶段的处理,输出的新文档中会包含一个新生成的数组列(用户可根据需要命名新key的名字 )。数组列存放的数据是来自 被Join 集合的适配文档,如果没有,集合为空(即 为[ ])

注意事项

  1. 需要3.2及以上版本才支持$lookup
  2. 需要4.0及以上版本才支持$convert

基本语法

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}

语法说明

语法说明
from同一个数据库下等待被Join的集合。
localField源集合中的match值,如果输入的集合中,某文档没有 localField这个Key(Field),在处理的过程中,会默认为此文档含有 localField:null的键值对。
foreignField待Join的集合的match值,如果待Join的集合中,文档没有foreignField值,在处理的过程中,会默认为此文档含有 foreignField:null的键值对
as为输出文档的新增值命名。如果输入的集合中已存在该值,则会覆盖掉

参考案例

1. 主表

主表id为ObjectId类型

db.getCollection('note').find();

查询结果:

{
    "_id" : ObjectId("5f9faba46b299d1336f9d316"),
    "noteCode" : "20201102144804000001",
    "userId" : 93,
    "title" : "标题",
    "content" : "内容"
},
{
    "_id" : ObjectId("5f9fabb06b299d1336f9d31c"),
    "noteCode" : "20201102144816000001",
    "userId" : 93,
    "title" : "标题",
    "content" : "内容"
}

2. 子表

外键noteId为String类型

/* 1 */
{
    "_id" : ObjectId("5f9faba46b299d1336f9d317"),
    "noteId" : "5f9faba46b299d1336f9d316",
    "imgId" : 316,
    "imgUrl" : "https://xxx/selection1577778815396.png",
    "createTime" : ISODate("2020-11-02T14:48:04.356+08:00")
}

/* 2 */
{
    "_id" : ObjectId("5f9faba46b299d1336f9d318"),
    "noteId" : "5f9faba46b299d1336f9d316",
    "imgId" : 3165,
    "imgUrl" : "https://xxx/selection157777881521.png",
    "createTime" : ISODate("2020-11-02T14:48:04.356+08:00")
}

3. 关联查询,将关联ID类型转换为一致(objectId to string)

db.getCollection("note").aggregate(
    [{
        "$project": 
        {
            "id": 
            {
                "$convert": {
                    "input": "$_id",
                    "to": "string"
                }
            },
            "noteCode": 1
        }
    }, {
        "$lookup": 
        {
            "from": "noteImage",
            "localField": "id",
            "foreignField": "noteId",
            "as": "image_docs"
        }
    }]
);

输出结果:

{
    "_id" : ObjectId("5f9faba46b299d1336f9d316"),
    "noteCode" : "20201102144804000001",
    "id" : "5f9faba46b299d1336f9d316",
    "image_docs" : [ 
        {
            "_id" : ObjectId("5f9faba46b299d1336f9d317"),
            "noteId" : "5f9faba46b299d1336f9d316",
            "imgId" : 316,
            "imgUrl" : "https://xxx/selection1577778815396.png",
            "createTime" : ISODate("2020-11-02T14:48:04.356+08:00")
        }, 
        {
            "_id" : ObjectId("5f9faba46b299d1336f9d318"),
            "noteId" : "5f9faba46b299d1336f9d316",
            "imgId" : 3165,
            "imgUrl" : "https://xxx/selection1577778815396.png",
            "createTime" : ISODate("2020-11-02T14:48:04.356+08:00")
        }
    ]
}

4. 关联查询,将关联ID类型转换为一致(string to objectId)

db.getCollection("noteImage").aggregate(
    [{
        "$project": 
        {
            "nid": 
            {
                "$convert": {
                    "input": "$noteId",
                    "to": "objectId"
                }
            },
            "imgId": 1
        }
    }, {
        "$lookup": 
        {
            "from": "note",
            "localField": "nid",
            "foreignField": "_id",
            "as": "noteDocs"
        }
    }]
);

输出结果:

// 1
{
    "_id": ObjectId("5fa9eab6e7e2af281425d0c9"),
    "imgId": 2686,
    "nid": ObjectId("5fa9eab6e7e2af281425d0c8"),
    "noteDocs": [
        {
            "_id": ObjectId("5fa9eab6e7e2af281425d0c8"),
            "noteCode": "9223372036854775807",
            "userId": NumberInt("99"),
            "title": "联调专用",
            "content": "联调数据"           
        }
    ]
}

// 2
{
    "_id": ObjectId("5fa9ee7ae7e2af281425d10a"),
    "imgId": 2872,
    "nid": ObjectId("5fa9ee7ae7e2af281425d109"),
    "noteDocs": [
        {
            "_id": ObjectId("5fa9ee7ae7e2af281425d109"),
            "noteCode": "9223372036854775807",
            "userId": NumberInt("90"),
            "title": "吃饭",
            "content": "吃饭"
        }
    ]
}
  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
MongoDB,$lookup操作符可以用于实现多表连接查询。它可以将两个集合的文档进行关联,并返回一个新的文档,其包含了两个集合匹配的文档信息。而在进行$lookup操作之后,我们可以使用$project操作符来对查询结果进行进一步的处理,以选择需要显示的字段或者添加新的字段。 例如,假设我们有两个集合"orders"和"customers",它们的结构分别如下: orders集合: ``` { "_id": ObjectId("5f94e5c0d286db2d3ad3a71c"), "order_id": 1, "customer_id": ObjectId("5f94e5c0d286db2d3ad3a71a"), "product": "computer", "amount": 3 } ``` customers集合: ``` { "_id": ObjectId("5f94e5c0d286db2d3ad3a71a"), "name": "Tom", "age": 25, "address": "New York" } ``` 现在我们希望查询orders集合的文档,并将其与customers集合的文档进行关联,以获取订单对应的客户信息。我们可以使用以下的$lookup和$project操作来实现: ``` db.orders.aggregate([ { $lookup: { from: "customers", localField: "customer_id", foreignField: "_id", as: "customer_info" } }, { $project: { "order_id": 1, "product": 1, "amount": 1, "customer_name": "$customer_info.name", "customer_age": "$customer_info.age", "customer_address": "$customer_info.address" } } ]) ``` 在上述代码,$lookup操作符用于将orders集合的"customer_id"字段与customers集合的"_id"字段进行关联,并将匹配的文档信息存储在一个新的字段"customer_info"。而$project操作符则用于对查询结果进行处理,选择需要显示的字段,并添加新的字段"customer_name"、"customer_age"和"customer_address"来显示客户的姓名、年龄和地址。 参考资料: - MongoDB官方文档:$lookup - MongoDB官方文档:$project

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值