• mongodb多表查询(附带pymongo实例)


    mongodb有$lookup可以做多表查询

    举个例子

    数据如下

    db.orders.insert([
       { "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 },
       { "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 },
       { "_id" : 3  }
    ])
    db.inventory.insert([
       { "_id" : 1, "sku" : "almonds", description: "product 1", "instock" : 120 },
       { "_id" : 2, "sku" : "bread", description: "product 2", "instock" : 80 },
       { "_id" : 3, "sku" : "cashews", description: "product 3", "instock" : 60 },
       { "_id" : 4, "sku" : "pecans", description: "product 4", "instock" : 70 },
       { "_id" : 5, "sku": null, description: "Incomplete" },
       { "_id" : 6 }
    ])

    聚合操作如下

    db.orders.aggregate([
     {
     $lookup:
     {
      from: "inventory",
      localField: "item",
      foreignField: "sku",
      as: "inventory_docs"
     }
     },
    ])

    上面的代码意思是,从order表中取item字段作为inventory表中sku的查询条件,然后把数据保存到inventory_docs字段,

    等价于mysql中的

    SELECT *, inventory_docs
    FROM orders
    WHERE inventory_docs IN (SELECT *
    FROM inventory
    WHERE sku= orders.item);

    下面用pymongo实现

    from pymongo import MongoClient
    
    def test():
        client = MongoClient()
        db = client[db_name]
        db['orders'].aggregate([{'$lookup':{'from': "inventory", "localField": "item", "foreignField": "sku", "as": "inventory_docs"}}])

    这样就实现了上述的效果了

    上述操作返回以下结果

    {
       "_id" : 1,
       "item" : "almonds",
       "price" : 12,
       "quantity" : 2,
       "inventory_docs" : [
          { "_id" : 1, "sku" : "almonds", "description" : "product 1", "instock" : 120 }
       ]
    }
    {
       "_id" : 2,
       "item" : "pecans",
       "price" : 20,
       "quantity" : 1,
       "inventory_docs" : [
          { "_id" : 4, "sku" : "pecans", "description" : "product 4", "instock" : 70 }
       ]
    }
    {
       "_id" : 3,
       "inventory_docs" : [
          { "_id" : 5, "sku" : null, "description" : "Incomplete" },
          { "_id" : 6 }
       ]
    }

    看起来蛮方便的,但是其实很麻烦,如果我们只想显示inventory表中的某些字段,这样不符合我们的要求

    这时候就需要用到$project和$arrayElemAt

    如果我们只想显示inventory中的instock字段的话应该这样做

    db.orders.aggregate([
     {
     $lookup:
     {
      from: "inventory",
      localField: "item",
      foreignField: "sku",
      as: "inventory_docs"
     }
     },
     {
     $project:
     {
        'instock': {'$arrayElemAt':['$inventory_docs.instock', 0]}
      },
     },
    ])

    返回的结果是

    {'_id': 1.0, 'instock': 120.0}
    {'_id': 2.0, 'instock': 70.0}
    {'_id': 3.0}

    之前orders的数据好像没了,不用着急,在project里面添加想要返回的数据项即可

    如我想要返回orders的price字段,在$project中添加{'price':1}即可,其他同

    lookup更多详细用法

    project可以指定返回的内容

     $project:
     {
        'sku':1, 'item':1,
     }

    指定返回sku和item

    也可以重命名

    $project:
    {
        'test': '$sku',
        'item': 1,
    }

    将sku字段重命名为test返回

    https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/index.html

  • 相关阅读:
    XML 编码
    XML CDATA
    XML 命名空间
    XML 解析器
    XML XMLHttpRequest 对象
    XML 和CSS
    XML 验证
    XML 属性
    XML 元素
    XML 语法规则
  • 原文地址:https://www.cnblogs.com/lgh344902118/p/8656266.html
Copyright © 2020-2023  润新知