使用aggregate 聚合管道、使用 populate 实现关联查询
一、mongoose中两个表关联查询aggregate
1、案例一
db.js
//连接数据库
var mongoose = require('mongoose');
//useNewUrlParser这个属性会在url里识别验证用户所需的db,未升级前是不需要指定的,升级到一定要指定。
mongoose.connect('mongodb://127.0.0.1:27017/eggcms', {
useNewUrlParser: true }, function (err) {
if (err) {
console.log(err);
return;
}
console.log('数据库连接成功')
});
module.exports = mongoose;
order.js
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');
order_item.js
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');
最外层order.js
/*
db.order.aggregate([
{
$lookup:
{
from: "order_item",
localField: "order_id",
foreignField: "order_id",
as: "items"
}
},
{
$match:{"all_price":{$gte:90}}
}
])
*/
var OrderModel = require('./model/order.js');
//查询order 表的数据
/*
OrderModel.find({},function(err,docs){
console.log(docs);
})
*/
//order表关联order_item
OrderModel.aggregate([
{
$lookup:
{
from: "order_item",
localField: "order_id",
foreignField: "order_id",
as: "items"
}
},
{
$match: {
"all_price": {
$gte: 90 } }
}
], function (err, docs) {
if (err) {
console.log(err);
return;
}
console.log(JSON.stringify(docs))
})
2、案例二
app.js
/*
db.order.aggregate([
{
$lookup:
{
from: "order_item",
localField: "order_id",
foreignField: "order_id",
as: "items"
}
},
{
$match:{"all_price":{$gte:90}}
}
])
*/
/*查询order_item,找出商品名称是酸奶的商品,酸奶这个商品对应的订单的订单号以及订单的总价格*/
var OrderItemModel = require('./model/order_item.js');
var OrderModel = require('./model/order.js');
var mongoose = require('mongoose');
//第一种实现方式
/*
OrderItemModel.find({ "_id": "5b743da92c327f8d1b360546" }, function (err, docs) {
// console.log(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) {
//console.log(order);
order_item[0].order_info = order[0];
console.log(order_item)
})
})
*/
//第二种方式
//mongoose中获取ObjectId mongoose.Types.ObjectId
OrderItemModel.aggregate([
{
$lookup:
{
from: "order",
localField: "order_id",
foreignField: "order_id",
as: "order_info"
}
}, {
$match: {
_id: mongoose.Types.ObjectId('5b743da92c327f8d1b360546') }
}
], function (err, docs) {
if (err) {
console.log(err)
return;
}
console.log(JSON.stringify(docs))
})
其余都一样
二、mongoose中多表(N个表)关联查询aggregate
db.js
//连接数据库
var mongoose=require('mongoose');
//useNewUrlParser这个属性会在url里识别验证用户所需的db,未升级前是不需要指定的,升级到一定要指定。
mongoose.connect('mongodb://127.0.0.1:27017/eggcms',{
useNewUrlParser: true },function(err){
if(err){
console.log(err);
return;
}
console.log('数据库连接成功')
});
module.exports=mongoose;
user.js
var mongoose = require('./db.js');
var UserSchema = new mongoose.Schema({
username: {
type: String, unique: true },
password: String,
name: String,
age: Number,
sex: String,
tel: Number,
status: {
type: Number,
default: 1
}
});
module.exports = mongoose.model('User', UserSchema, 'user');
article.js
var mongoose = require('./db.js');
var Schema = mongoose.Schema;
var ArticleSchema = new Schema({
title: {
type: String, unique: true
},
cid: {
type: Schema.Types.ObjectId
}, /*分类 id*/
author_id: {
type: Schema.Types.ObjectId
}, /*用户的id*/
author_name: {
type: String
},
descripton: String,
content: String
});
module.exports = mongoose.model('Article', ArticleSchema, 'article');
articlecate.js
var mongoose = require('./db.js');
var ArticleCateSchema = new mongoose.Schema({
title: {
type: String,
unique: true
},
descripton: String,
addtime: {
type: Date
}
});
module.exports = mongoose.model('ArticleCate', ArticleCateSchema, 'articlecate');
app.js
/*
db.order.aggregate([
{
$lookup:
{
from: "order_item",
localField: "order_id",
foreignField: "order_id",
as: "items"
}
},
{
$match:{"all_price":{$gte:90}}
}
])
*/
var ArticleModel = require('./model/article.js');
//查询文章信息
/*
ArticleModel.find({},function(err,docs){
console.log(docs);
})
*/
//查询文章信息 并显示文章的分类 以及文章的作者信息
//两个表关联查询
/*
ArticleModel.aggregate([
{
$lookup: {
from: "articlecate",
localField: "cid",
foreignField: "_id",
as: "cate"
}
}
],function(err,docs){
console.log(docs[2].cate)
})
*/
//三个表关联查询
ArticleModel.aggregate([
{
$lookup: {
from: "articlecate",
localField: "cid",
foreignField: "_id",
as: "cate"
}
},
{
$lookup: {
from: "user",
localField: "author_id",
foreignField: "_id",
as: "user"
}
}
], function (err, docs) {
console.log(JSON.stringify(docs));
})
app_add.js 这个文件是用来给数据库添加信息的
var ArticleCateModel = require('./model/articlecate.js');
var UserModel = require('./model/user.js');
var ArticleModel = require('./model/article.js');
//分类的增加
// var cate=new ArticleCateModel({
// title:'国内新闻',
// description:'国内新闻'
// })
// cate.save();
//增加用户
// var user= new UserModel({
// username :'lisi',
// password:'13214lkisisgfdsgsdsg',
// name:'李四',
// age:20,
// sex:'男',
// tel:124212142151
// })
// user.save();
var article = new ArticleModel();
article.title = "这是一个国内新闻11111111"
article.cid = '5b7900bbf3965813d41216c1'; /*国内新闻*/
article.author_id = '5b7901332d552617b09af422';
article.author_name = '张三';
article.descripton = '这是一个国内新闻11111111 此处省略300字';
article.content = '这是一个国内新闻11111111'
article.save();
三、 Populate 实现多个表的关联查询
1、定义 ref
var ArticleSchema = new Schema({
title:{
type: String,
unique: true
},
cid : {
type: Schema.Types.ObjectId,
ref:'ArticleCate' //model 的名称
}, /*分类 id*/
author_id:{
type: Schema.Types.ObjectId,
ref:'User'
}, /*用户的 id*/
author_name:{
type:String
},
descripton:String,
content : String
})
2、关联查询
ArticleModel.find({
}).populate('cid').populate('author_id').exec(function(err,docs){
console.log(docs)
})
案例,在上面案例的基础上改造
article.js
var mongoose = require('./db.js');
var Schema = mongoose.Schema;
var ArticleSchema = new Schema({
title: {
type: String, unique: true
},
cid: {
type: Schema.Types.ObjectId,
ref: "ArticleCate" //cid和 文章分类建立关系。 model
}, /*分类 id*/
author_id: {
type: Schema.Types.ObjectId,
ref: "User" //author_id和 用户表建立关系。 model
}, /*用户的id*/
author_name: {
type: String
},
descripton: String,
content: String
});
module.exports = mongoose.model('Article', ArticleSchema, 'article');
app.js
//注意使用 populate需要引入用到的model
var ArticleCateModel = require('./model/articlecate.js');
var ArticleModel = require('./model/article.js');
var UserModel = require('./model/user.js');
//文章表和 分类表的关联
// ArticleModel.find({}).populate('cid').exec(function(err,docs){
// console.log(docs);
// })
//三个表关联
ArticleModel.find({
}).populate('cid').populate('author_id').exec(function (err, docs) {
console.log(docs);
})
// ArticleModel.aggregate 建议使用