之前写过一篇mongoose常用的经典记录,用来自查询,因为老是忘记mongo的书写格式,所以索性将自己的学习笔记放到博客上,并供大家参考,如果代码有问题请在评论指出。
一、创建数据库
- 使用原生,
insert
和save
的区别是:insert只会无脑增加,而sava是“有则更新,无则增加”;
//插入一条
db.user.insert({name:"a"})
//插入多条
db.user.insertMany({name:"a"},{name:"b"})
- 使用mongoose创建基础格式;
const mongoose = require('mongoose')
congst schema = new mongoose.Schema({
name:{
type:String,
require:true
}
})
module.exports = mongoose.model('user',schema)
- 使用mongoose添加数据(
create
和save
的区别是:create只会无脑增加,而sava是“有则更新,无则增加);
user.create(数据对象) //如:request.body.user
二、简单查询
findOne()
只会返回符合条件第一个文档,db.user.find()
会返回所有符合条件的文档;
格式:({“键名”:“键值”})
例:
db.user.find({'name': "小明"})
$and
和$or
是常用的关键符。顾名思义,and是需要一起实现,or是符合之一;
例1:查找名字是小明且性别是男的字段(请注意$and的位置)
db.user.find(
{
$and:[
{'name': "小明"},
{'sex': "男"}
]
}//第一个{}里面放条件
)
例2:查找名字是小明且性别是男或者年龄是18的字段(请注意$or的位置)
db.user.find(
{
'name': "小明",
$or:[
{'sex': "男"},
{'age': 18}
]
}//第一个{}里面放条件
)
投影器
,设置需要返回的字段值,去除无用的数据字段;
例:假设小明的一条文档里有名字、性别、年龄和成绩,那么我只需要返回他的成绩字段。
db.user.find(
{
'name': "小明",
},//第一个{}里面放条件
{
"grade":1 //第二个{}里放投影
}
)
- 使用
正则表达式
进行条件搜索
例:找出名字以St
或者Te
开头的且班级以为Che
开头的所有人
db.user.find({'name': /(St|Te)*/i, 'class':/(Che)*/i})
- 更多搜索需求请查看后续内容
四、更新(添加)和移除字段
update()
和$set()
用于更新单个文档,注意update()
默认只更新第一个符合条件的数据,想要更新所有的数据,需要配合使用multi
;
格式:({条件},{$set{数据}})
例:将符合条件的第一个小明的性别改成女
db.user.update(
{'name': "小明"}, //第一个{}里面放条件
{
$set:{'sex': "女"}
}
)
例:将所有小明的性别改成女
db.user.update(
{'name': "小明"}, //第一个{}里面放条件
{
$set:{'sex': "女"}
},
{
"multi":true //匹配所有符合条件的
}
)
$push
和$addToset
可以实现插入文档的功能,结合$each
可以插入多个;
$push
直接将值插入一个文档中,并不管相同的值是否已经在数组中存在了。$addToSet
判断相同的值是否在数组中已经存在,如存在则不再重复加入。
db.user.update(
{'name': "小明"}, //第一个{}里面放条件
{
$addToset{
"grade": 89 //插入成绩,并且检测是否有重复
}
}
)
添加多个值到文档中
db.students.update(
{ name: "小明" },
{
$push:
{
grade: {
$each: [ 90, 92, 89 ]
}
}
}
)
update()
和$unset()
通常用来移除字段,同样的只作用于符合条件的第一个文档,将multi
设置为true
即可作用所有文档;
例:将所有user
里面的age
字段移除
db.user.update(
{'name': "小明"}, //第一个{}里面放条件
{
$unset:{'age': ""} //移除age
},
{
"multi":true //匹配所有符合条件的
}
)
五、删除操作
remove()
通常同来移除文档,默认作用于匹配出的第一个;
例:删除所有name
是小明的数据
db.user.remove(
{'name': "小明"}, //第一个{}里面放条件
{
"multi":true //匹配所有符合条件的
}
)
drop()
用来删除整个集合,返回结果true表示删除成功;
db.user.drop()
六、条件操作符
$lt
小于$lte
小于等于$gt
大于$gte
大于等于$in
包含(匹配单值)$all
包含(多值),常用于数组多值匹配$not
非$exists
是否存在
例:找出年龄小于18岁的人
db.user.find(
{
'name': { "$lt":18 }
} //第一个{}放条件
)
例:找出C1 或者C2班级的同学
db.user.find(
{
'name': { "$in":["C1","C2"] }
} //第一个{}放条件
)
例:设置上限和下限,找出大于16岁,小于18岁的人
db.user.find(
{
'age': { "$gt":16,"$lt":18 }
} //第一个{}放条件
)
例:找出性别是“男”或者班级的值是C1 或 C2的人,并且年龄要小于18岁
db.user.find(
{
$or:[{
"sex":'男',
"class":{ "$in":["C1","C2"] }
}],
"age":{ "$lt":18 }
} //第一个{}放条件
)
七、其它使用频率极高的常用操作
所有的操作符是可以连续写下去的,类似jquery;
$count()
根据条件查询符合要求的文档的总数量;
例:
db.user.find( {'name': "小明"} ).count() //返回查询出文档的总数量
$sort()
可以将结果进行指定字段进行排序,1是升序,0是降序;
例:将查找到的性别为 “男” 的字段按照成绩进行升序排序。
db.user.find({'sex': "男"}).sort(1);
limit(数字)
可以限制返回的数量;
例:只返回两条文档
db.user.find({'name': "小明"}).limit(2) //
skip(数字)
可以跳过一定数量的文档进行查询,将它于limit()
进行配合,可以做分页功能查询;
例:跳过前2条数据,再进行查询,并且只要查询出10条数据
db.user.find({'name': "小明"}).skip(2).limit(10) //
$size
可以通过值的数量(常用于数组),来当作条件匹配文档
例:查找职位(数组)拥有2个的人
db.user.find({'position':{$size: 2}})
八、多表关联:aggregate()
-
$lookup
:根据一个集合的字段,查出另一个
相关联的集合所有信息。有集合A和集合B,他们的数据描述
同一个事务
,并且A中用的字段是a
,B中用的字段是b
,那么$lookup
可以a与b进行关联,相当于做成外键
,并且把B(也可以是A)所有的匹配字段拆出来给对方。
用法:
user.aggregate(
$lookup:{
from: 被join(拆)的集合,
localField: 原集合中 user 的 关键字,
foreignField: 被拆集合中的 关键字,
as: 新增的 字段名
}
)
例子:
集合A:
{ "name":a1, "modelA": CCC },
{ "name":a2, "modelA": CCC },
{ "name":a3, "modelA": DDD }
集合B:
{ "modelB": CCC, "money":1,"age": 18},
进行关联
A.aggregate(
$lookup:{
from: "B",
localField: "modelA",
foreignField: "modelB",
as: newB
}
)
会得到:
{ "name":a1, "modelA": CCC, "newB":[ { "money":1 , "age": 18 } ]},
{ "name":a2, "modelA": CCC, "newB":[ { "money":1 , "age": 18 } ]},
{ "name":a3, "modelA": DDD, "newB":[] }
更多的$lookup
细节功能可以查看:$lookup参考博客文章
先写到这里,手有点酸,后面会继续更新,请点赞、收藏、收藏素值三连,谢谢!