使用Mongoose操作MongoDB数据库进行关联查询是一种比较常见的操作,操作方式有哪几种呢?下面用一个具体的案例来演示。
首先模拟一点数据,分别有 order 和 order_item 两个集合:
order 集合里的数据
{
"_id": ObjectId("5e6f15c1eb57cc45bde8130b"),
"order_id": "1",
"uid": 10,
"trade_no": "111",
"all_price": 100,
"all_num": 2
}
{
"_id": ObjectId("5e6f15cbeb57cc45bde8130c"),
"order_id": "2",
"uid": 7,
"trade_no": "222",
"all_price": 90,
"all_num": 2
}
{
"_id": ObjectId("5e6f15d4eb57cc45bde8130d"),
"order_id": "3",
"uid": 9,
"trade_no": "333",
"all_price": 20,
"all_num": 6
}
order_item 集合里的数据
{
"_id": ObjectId("5e6f15dbeb57cc45bde8130e"),
"order_id": "1",
"title": "商品鼠标 1",
"price": 50,
"num": 1
}
{
"_id": ObjectId("5e6f15e2eb57cc45bde8130f"),
"order_id": "1",
"title": "商品键盘 2",
"price": 50,
"num": 1
}
{
"_id": ObjectId("5e6f15e8eb57cc45bde81310"),
"order_id": "1",
"title": "商品键盘 3",
"price": 0,
"num": 1
}
{
"_id": ObjectId("5e6f15f1eb57cc45bde81311"),
"order_id": "2",
"title": "牛奶",
"price": 50,
"num": 1
}
{
"_id": ObjectId("5e6f15faeb57cc45bde81312"),
"order_id": "2",
"title": "酸奶",
"price": 40,
"num": 1
}
{
"_id": ObjectId("5e6f1603eb57cc45bde81313"),
"order_id": "3",
"title": "矿泉水",
"price": 2,
"num": 5
}
{
"_id": ObjectId("5e6f160aeb57cc45bde81314"),
"order_id": "3",
"title": "毛巾",
"price": 10,
"num": 1
}
假设要做这样的一个操作:
查询 order_item 集合,找出商品名称是酸奶的商品以及所对应的订单的信息,酸奶所对应的ID为 "5e6f15faeb57cc45bde81312"
查询方式一:
1. 在 order_item 中查出 order_id,然后通过order_id 查询 order 集合,查出订单的信息。
定义 order 的 schema,导出模型,文件名为 order.js
// 引入自定义的连接数据库的文件
var mongoose=require('./db.js');
// 定义订单的schema
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');
定义 order_item 的 schema ,导出模型,文件名为 order_item.js
// 引入自定义的连接数据库的文件
var mongoose=require('./db.js');
// 定义订单商品列表的schema
var OrderItemSchema=mongoose.Schema({
order_id:String,
title:String,
price:Number,
num:Number
});
module.exports=mongoose.model('OrderItem',OrderItemSchema,'order_item');
在需要查询的文件里引入两个模型文件,执行操作
var OrderItemModel = require('./model/order_item.js');
var OrderModel = require('./model/order.js');
OrderItemModel.find({ "_id": "5e6f15faeb57cc45bde81312" }, function (err, docs) {
var order_item = JSON.parse(JSON.stringify(docs));
var order_id = order_item[0].order_id;
OrderModel.find({ "order_id": order_id }, function (err, order) {
// 将该商品的订单信息添加到商器信息里
order_item[0].order_info = order[0];
console.log(order_item)
})
})
查询方式二:
定义 order_item 的 schema ,导出模型,文件名为 order_item.js
// 引入自定义的连接数据库的文件
var mongoose=require('./db.js');
// 定义订单商品列表的schema
var OrderItemSchema=mongoose.Schema({
order_id:String,
title:String,
price:Number,
num:Number
});
module.exports=mongoose.model('OrderItem',OrderItemSchema,'order_item');
在需要查询的文件里引入定义的模型文件,执行操作
// 引入mongoose方便获取ID
var mongoose = require('mongoose');
var OrderItemModel = require('./model/order_item.js');
OrderItemModel.aggregate([
{
$lookup:
{
from: "order",
localField: "order_id",
foreignField: "order_id",
as: "order_info"
}
},
{
$match: { _id: mongoose.Types.ObjectId('5e6f15faeb57cc45bde81312') }
}
], function (err, docs) {
if (err) {
console.log(err)
return;
}
console.log(JSON.stringify(docs))
})
相比查询方式一,第二种方式只需要定义一个模型,写法会更优雅一点,也是mongoose推荐的方式。
需要注意的是,在 mongoose 里获取 ObjectId,要用 mongoose.Types.ObjectId 才能获取的到。