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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM