Mongoose 兩個表關聯查詢aggregate
通常兩個表關聯查詢的時候,是一種一對多的關系,比如訂單與訂單詳情就是一對多的關系,一個訂單下面有多個商品
數據模擬
首先我們先將數據模擬出來,先選擇數據庫
use eggcms
db.order.insert({"order_id":"1","uid":10,"trade_no":"111","all_price":100,"all_num":2}) db.order.insert({"order_id":"2","uid":7,"trade_no":"222","all_price":90,"all_num":2}) db.order.insert({"order_id":"3","uid":9,"trade_no":"333","all_price":20,"all_num":6}) db.order_item.insert({"order_id":"1","title":"商品鼠標 1","price":50,num:1}) db.order_item.insert({"order_id":"1","title":"商品鍵盤 2","price":50,num:1}) db.order_item.insert({"order_id":"1","title":"商品鍵盤 3","price":0,num:1}) db.order_item.insert({"order_id":"2","title":"牛奶","price":50,num:1}) db.order_item.insert({"order_id":"2","title":"酸奶","price":40,num:1}) db.order_item.insert({"order_id":"3","title":"礦泉水","price":2,num:5}) db.order_item.insert({"order_id":"3","title":"毛巾","price":10,num:1})
代碼演示:使用Mongoose來實現order集合和order_item集合的關聯查詢
Mongoose中aggregate管道的語法跟原生MongoDB的語法是一樣的
db.order.aggregate([ { $lookup: { from: "order_item", localField: "order_id", foreignField: "order_id", as: "items" } } ])
第一步:創建model文件夾並且創建db.js(連接數據庫)
const mongoose = require('mongoose'); mongoose.connect('mongodb://127.0.0.1:27017/eggcms', { useNewUrlParser: true }, (err) => { if(err){ return console.log(err); } console.log('數據庫連接成功') }); module.exports = mongoose
第二步:分別創建order.js和order_item.js這兩個model模塊
var mongoose = require('./db.js'); var OrderSchema=mongoose.Schema({ order_id: String, uid: Number, trade_no: String, all_price: Number, all_num: Number }) module.exports = mongoose.model('Order',OrderSchema,'order');
var mongoose = require('./db.js'); var OrderItemSchema = mongoose.Schema({ order_id: String, title: String, price: Number, num: Number }) module.exports = mongoose.model('OrderItem',OrderItemSchema,'order_item');
第三步:在app.js中進行兩個集合的關聯查詢
let OrderModel = require('./model/order.js'); // order表關聯order_item OrderModel.aggregate([ { $lookup: { from: "order_item", localField: "order_id", foreignField: "order_id", as: "items" } } ], (err, docs) => { if(err){ return console.log(err) } console.log(JSON.stringify(docs)) })
將查詢出來的數據復制出來解析成JSON格式會更清晰,找一個在線格式化的網址即可,實際項目中不需要
Mongoose 兩個表關聯查詢aggregate練習
需求:查詢order_item,找出商品名稱是酸奶的商品,酸奶這個商品對應的訂單的訂單號以及訂單的總價格
第一種實現方式
思路:首先通過酸奶這個商品的_id查詢order_item集合,找到這個商品,並且獲取商品中的order_id,然后再通過order_id去查詢order集合
let OrderItemModel = require('./model/order_item.js'); let OrderModel = require('./model/order.js'); OrderItemModel.find({"_id":"5cde69c24a988180bdf060b0"}, (err,docs) => { // console.log(docs); let order_item = JSON.parse(JSON.stringify(docs)); let order_id = order_item[0].order_id; OrderModel.find({"order_id":order_id}, (err,order) => { order_item[0].order_info = order[0]; console.log(order_item) }) })
第二種實現方式
思路:直接使用$match:條件匹配,然后進行兩個表關聯查詢
mongoose中獲取ObjectId (mongoose.Types.ObjectId)
let OrderItemModel = require('./model/order_item.js'); let mongoose = require('mongoose'); OrderItemModel.aggregate([ { $lookup: { from: "order", localField: "order_id", foreignField: "order_id", as: "order_info" } },{ $match:{_id: mongoose.Types.ObjectId('5cde69c24a988180bdf060b0')} } ], (err,docs) => { if(err){ console.log(err) return; } console.log(JSON.stringify(docs)) })