mongodb lookup (left join) 總結

product表

db.product.insert({"_id":1,"productname":"商品1","price":15})
db.product.insert({"_id":2,"productname":"商品2","price":36})

 

orders表

db.orders.insert({"_id":1,"pid":1,"ordername":"訂單1"})
db.orders.insert({"_id":2,"pid":2,"ordername":"訂單2"})
db.orders.insert({"_id":3,"pid":2,"ordername":"訂單3"})
db.orders.insert({"_id":4,"pid":1,"ordername":"訂單4"})

orders中通過pid關聯product表

 

left jon:

 db.product.aggregate([     //注意: 這裏是  db.product, 即主表名稱
     {
       $lookup:
         {
           from: "orders",  //注意: 這裏是  orders, 需要關聯的表
           localField: "_id",     //product表需要關聯的鍵(主表中的key)
           foreignField: "pid",   //orders表中對應的鍵 (關聯表中的key)
           as: "inventory_docs"   //集合名,存放關聯的結果數組
         }
    }
 ])

結果:

/* 1 */
{
    "_id" : 1.0,
    "productname" : "商品1",
    "price" : 15.0,
    "inventory_docs" : [ 
        {
            "_id" : 1.0,
            "pid" : 1.0,
            "ordername" : "訂單1"
        }, 
        {
            "_id" : 4.0,
            "pid" : 1.0,
            "ordername" : "訂單4"
        }
    ]
}

/* 2 */
{
    "_id" : 2.0,
    "productname" : "商品2",
    "price" : 36.0,
    "inventory_docs" : [ 
        {
            "_id" : 2.0,
            "pid" : 2.0,
            "ordername" : "訂單2"
        }, 
        {
            "_id" : 3.0,
            "pid" : 2.0,
            "ordername" : "訂單3"
        }
    ]
}

-----------------------------------

加入查詢條件: 產品 price > 20 的訂單

  db.product.aggregate([
      {
        $lookup:
          {
            from: "orders",
            localField: "_id",
            foreignField: "pid",
            as: "inventory_docs"
          }
     },
     { $match : { price : {$gt:20} } }
  ])

其他舉例: {$match:{name:"小明","orders.xxx":"jjj"}}

 

-----------------------------------

使用$project來指定我要獲取的字段,比如我只需要inventory_docs字段就可以了

  db.product.aggregate([
      {
        $lookup:
          {
            from: "orders",
            localField: "_id",
            foreignField: "pid",
            as: "inventory_docs"
          }
     },
     { $match : { price : {$gt:20} } },
     {$project:{"inventory_docs":1,"_id":0}}
  ])

-----------------------------------

多表關聯:

三表關聯

 

$match爲條件拼接,若條件爲關聯表中的字段,則需要根據關聯表相應的結果集(as)屬性後面名稱拿到<例:as:“result”,獲取字段爲result._id>,若爲主表字段條件則直接寫就可以

增加排序分頁功能
分頁功能和排序功能只需要在關聯的的aggregation中添加就可以實現,其中pageEntity.getPage()爲分頁的頁碼,pageEntity.getLimit()爲條數 

使用$unwind將數據打散:

db.product.aggregate([     //注意: 這裏是  db.product, 即主表名稱
     {
       $lookup:
         {
           from: "orders",  //注意: 這裏是  orders, 需要關聯的表
           localField: "_id",     //product表需要關聯的鍵(主表中的key)
           foreignField: "pid",   //orders表中對應的鍵 (關聯表中的key)
           as: "inventory_docs"   //集合名,存放關聯的結果數組
         },
         {$unwind:"$inventory_docs"}
    }
 ])

inventory_docs 中本來存放的是一個數組,  $unwind:"inventory_docs" 將查詢結果分成多條, inventory_docs變成一個對象

 

---------------------------------

ps:一些小坑
$lookup是如果涉及關聯"_id",注意兩個字段的類型,用string類型匹配ObjectId類型是沒有結果的~~
_class字段也是有些作用的,比如說使用$sum時用作分組
數據處理後續:Document返回的值,如果用作前端返回,ObjectId是會被當成BSON解析的~ 

 

 

 

https://blog.csdn.net/harleylau/article/details/77899223

https://blog.csdn.net/qq_38145375/article/details/95347426

https://blog.csdn.net/DDKii/article/details/81504805

https://blog.csdn.net/molashaonian/article/details/86520054

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章