Node.js中实现MongoDB数据库的索引、多表关联查询
Node.js中实现MongoDB数据库的索引、多表关联查询
·
本文前置知识点:Mongoose增删改查基础
Node.js中实现MongoDB数据库的增删改查_番大茄子的博客-CSDN博客https://blog.csdn.net/SongD1114/article/details/124107324
一. Mongoose索引
索引是对数据库表中一列或多列值进行排序的一种结构,可以优化查询速度。
- 若有些字段用不着,就不要给他增加索引,否则会使插入数据的速度减慢。
- 若为一个字段设置了唯一索引,则该字段不能重复。
// 定义数据集合的映射,字段名称必须与数据库保持一致
var UserSchema = mongoose.Schema({
name: {
type: String,
index: true, // 普通索引
},
age: Number,
sn: { // 用户绑定设备的设备号
type: String,
unique: true, // 唯一索引
},
status: {
type: Number,
default: 1,
},
})
二. Mongoose两表关联查询
Mongoose聚合管道中的语法和原生MongoDB中聚合管道的语法是一样的。
先学习MongoDB聚合管道语法:
MongoDB 索引基础、聚合管道_番大茄子的博客-CSDN博客MongoDB 索引基础、唯一索引、复合索引、聚合管道https://blog.csdn.net/SongD1114/article/details/124278058用Mongoose实现聚合管道和关联查询:
const mongoose=require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/cms-test')
const OrderSchema=mongoose.Schema({
order_id:String,
uid:Number,
trade_no:String,
all_price:Number,
all_num:Number
})
const Order=mongoose.model('Order',OrderSchema,'order')
const OrderItemSchema=mongoose.Schema({
order_id:String,
title:String,
price:Number,
num:Number
})
const OrderItem=mongoose.model('OrderItem',OrderItemSchema,'order_item')
// 关联查询:order表关联order_item表
// 查询order表的数据时还要查询到每个订单下的商品
// 聚合管道中的语法和原生MongoDB中聚合管道的语法是一样的
Order.aggregate([
{
$lookup:{
from:"order_item",
localField:"order_id",
foreignField:"order_id",
as:"items"
}
},
{
$match:{"all_price":{$gte:90}}
}
],function(err,docs){
if(err) return console.log(err)
console.log(JSON.stringify(docs))
})
// 关联查询:order_item表关联order表
// 查询order_item表,找出商品名是“奶酪”的商品对应的订单号和订单的总价格
// 方法1,表关联
OrderItem.aggregate([
{
$lookup:{
from:"order",
localField:"order_id",
foreignField:"order_id",
as:"order_info"
}
},
{
$match:{"title":"奶酪"},
// 若此处match用的是ObjectId应写成 $match:{_id: mongoose.Types.ObjectId('12hrej3if78y3ab8d1sc8')}
}
],function(err,docs){
if(err) return console.log(err)
console.log(JSON.stringify(docs))
})
// 方法2,一个表查完再查另一个表
OrderItem.find({"title":"奶酪"},function(err,docs){
// 考虑浅拷贝和深拷贝问题
const order_item=JSON.parse(JSON.stringify(docs))
const order_id=order_item[0].order_id
Order.find({"order_id":order_id},function(err,order){
order_item[0].order_info=order[0]
console.log(order_item)
})
})
三. Mongoose多表关联查询
1. Mongoose使用聚合管道aggregate实现多表关联查询
推荐使用聚合管道实现关联查询,但只有在MongoDB 3.2以上版本可以使用聚合管道
const mongoose=require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/cms-test')
// 文章
const ArticleSchema=new mongoose.Schema({
title:{
type:String,
unique:true,
},
cid:{ // 分类
type:mongoose.Schema.Types.ObjectId,
},
author_id:{ // 用户id
type:mongoose.Schema.Types.ObjectId,
},
author_name:{
type:String,
default:'匿名',
},
description:String,
content:String,
})
const Article=mongoose.model('Article',ArticleSchema,'articles')
// 文章分类
const ArticleCateSchema=new mongoose.Schema({
title:{
type:String,
unique:true,
},
description:String,
addtime:{
type:Date
}
})
const ArticleCate=mongoose.model('ArticleCate',ArticleCateSchema,'articlecates')
// 用户
const UserSchema=new mongoose.Schema({
username:{
type:String,
unique:true,
},
password:String,
name:String,
sex:String,
age:Number,
tel:Number,
status:{
type:Number,
default:1
}
})
const User=mongoose.model('User',UserSchema,'users')
// 查询文章信息,并显示文章的分类以及文章的作者信息
Article.aggregate([
{
$lookup:{
from:"articlecates",
localField:"cid",
foreignField:"_id",
as:"cate"
}
},
{
$lookup:{
from:"users",
localField:"author_id",
foreignField:"_id",
as:"user"
}
},
],function(err,docs){
if(err) return console.log(err)
console.log(JSON.stringify(docs))
})
2. Mongoose使用populate实现多表关联查询
1. 搞清楚主键、外键
- articlecates表的主键:_id
- articlecates表的外键:articles表中的cid
- users表的主键:_id
- users表的外键:articles表中的author_id
2. 定义ref
ref 放在外键里,表示和哪个表关联。
3. 关联查询
注意:使用populate需要引入所有用到的model!!!
const mongoose=require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/cms-test')
// 文章
const ArticleSchema=new mongoose.Schema({
title:{
type:String,
unique:true,
},
cid:{ // 分类(外键)
type:mongoose.Schema.Types.ObjectId,
ref:'ArticleCate' // cid和文章分类表的Model建立关系
},
author_id:{ // 用户id(外键)
type:mongoose.Schema.Types.ObjectId,
ref:'User' // author_id和用户表的Model建立关系
},
author_name:{
type:String,
default:'匿名',
},
description:String,
content:String,
})
const Article=mongoose.model('Article',ArticleSchema,'articles')
// 文章分类
const ArticleCateSchema=new mongoose.Schema({
title:{
type:String,
unique:true,
},
description:String,
addtime:{
type:Date
}
})
const ArticleCate=mongoose.model('ArticleCate',ArticleCateSchema,'articlecates')
// 用户
const UserSchema=new mongoose.Schema({
username:{
type:String,
unique:true,
},
password:String,
name:String,
sex:String,
age:Number,
tel:Number,
status:{
type:Number,
default:1
}
})
const User=mongoose.model('User',UserSchema,'users')
// 文章表和分类表的关联
Article.find({}).populate('cid').exec(function(err,docs){
console.log(docs)
})
// 文章表和分类表以及用户表的关联
Article.find({}).populate('cid').populate('author_id').exec(function(err,docs){
console.log(docs)
})
扩展阅读:
Node.js实现服务器端通用CRUD接口_番大茄子的博客-CSDN博客https://blog.csdn.net/SongD1114/article/details/124101324
更多推荐
已为社区贡献7条内容
所有评论(0)