目录
(3)查询table2集合下的所有name为zhangsan的记录
(4)查询table2集合下name为zhangsan的其中一个记录
[(9)in,not in](#(9)in,not in)
[四.aggregate() 聚合操作](#四.aggregate() 聚合操作)
一.基础概念
mongodb中,基本的概念是文档,集合,数据库。
序号 | 基本概念 | 说明 |
---|---|---|
1 | database | 数据库 |
2 | collection | 集合,也称文档组,相当于mysql中的表table |
3 | ducument | 文档,相当于mysql表中的行,键值对结构,BSON(binary二进制) |
4 | field | 字段,也就是mysql表中的列 |
5 | index | 索引 |
[MongoDB中的重要概念] |
**关于主键的说明:**MongoDB自动将_id字段设置为主键。MongoDB不支持表的连接。
一个mongodb可以建立多个数据库,一个数据库可以创建多个集合,一个集合很总可以有多个文档,数据库存储在data中。
二.数据库的管理
1.创建数据库
创建数据库使用关键字use,创建并指定当前数据库,具体语法如下:
perl
# 1.创建数据库,例如创建并指定一个school数据库
use <databasename>
use school
# 2.查看当前数据库
db
# 3.查看所有数据库
show dbs
2.删除数据库
perl
# 1.先选中是哪个数据库
use school
# 2.删除数据库
db.dropDatabase()
二.集合的管理
集合相当于Mysql中的表结构table.
1.显示所有集合
perl
# 1.显示所有集合(表结构)
show tables;
show collections
2.创建集合
perl
# name是创建的集合名,option是可选参数,指定有关内存大小及索引的选项
db.createCollection(name,option):
3.删除当前集合
perl
db.school.drop()
4.向集合中插入元素
perl
# 1.向集合中插入单个元素,insertOne({k:v})
db.collection001.insertOne({"name":"jack"})
# 2.向集合中插入多个元素,insertMany({k1:v1},{k2:v2}......)
db.collection001.insertOne({"name":"jack"},{"age":18})
三.文档的管理
文档也就是mysql中的行
1.文档插入
每条文档在插入的时候,MongoDB都会维护一个_id作为唯一标识,_id默认会自动生成。
perl
# 1.插入1行
db.table2.insertOne({"name":"zhangsan"})
# 2.插入多行
db.table2.insertMany([
{"name":"zhangsan","age":15,"address":"xuzhou"},
{"name":"wangwu","age":20,"address":"nanj"}
])
# 3.当然也可以是这种形式的
document = ({"name":"wangwu","age":20,"address":"nanj",tags:['mysql','oracle'],like:100})
db.table2.insertMany([document])
2.文档的更新
文档的更新都是先查出来,再更新。
<query>: update的查询条件,类似sql update查询内的where后面的条件
<update>: update的对象和一些更新的操作符,也可以理解为sql update查询内set后面的
upsert: 可选,如果不存在update记录,是否插入objNew,true是插入,false不插入
multi: 可选,mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新 5.0之后是废弃的
**writeConcern:**可选,抛出异常的级别
java
db.collection.update(
<query>, // 相当于where操作
<update>, // 相当于set操作
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
注意语法:$set
perl
// 先查再更新,$set是set
// 更新一条,updateOne
db.table3.updateOne({title:"Oracle"},{$set:{title:"MongoDB是NoSQL键-值数据库"}})
3.文档的删除
Lua
// 删除集合下的所有文档
db.collection.deleteMany ({})
// 删除status等于A的所有文档
db.collection.deleteMany ({ status : "A" })
// 删除status等于D的一个文档
db.collection.delete.One ({ status : "D" })
// 当然也可以根据主键删除
db.table2.deleteOne({_id:ObjectId("64ef1442db2b4f63a830119c")})
4.文档查询
文档的查询十分重要,用的最多。
MongoDB 查询文档使用find 方法,**find()**方法以非结构化的方式来显示所有文档。
语法:
Lua
db.集合名称.find({<query>},....)
等于,不等于,大于等于,大于,小于等于,小于等,看下表:
|------|--------------------|---------------------------------|-----------------------|
| 操作 | 格式 | 例子 | mysql类比语句 |
| 等于 | {key:value} | db.集合名称.find({name:"zhangsan"}) | where name='zhangsan' |
| 不等于 | {key:{ne:value}} | db.集合名称.find({age:{ne:18}}) | where age != 18 |
| 小于 | {key:{lt:value}} | db.集合名称.find({age:{lt:18}}) | where age < 18 |
| 小于等于 | {key:{lte:value}} | db.集合名称.find({age:{lte:18}}) | where age <= 18 |
| 大于 | {key:{gt:value}} | db.集合名称.find({age:{gt:18}}) | where age > 18 |
| 大于等于 | {key:{gte:value}} | db.集合名称.find({age:{gte:18}}) | where age >= 18 |
[文档查询对比语法]
(1)查询基本语法:
第一个{}放的是where条件,第二个放的是显示哪些列,或者不显示哪些列,列的值设置为0表示不显示,设置为1设置为显示。
Lua
db.table2.find({},{})
(2)查询table2集合下的所有文档
Lua
db.table2.find()
(3)查询table2集合下的所有name为zhangsan的记录
等值查询,name="zhangsan"
Lua
db.table2.find({name:"zhangsan"})
(4)查询table2集合下name为zhangsan的其中一个记录
Lua
db.table2.findOne({name:"zhangsan"})
(5)查询结果中的某些列
默认为0,0表示不显示,1表示显示该列,1和0是不能同时用的
相当于select name,address from table2
Lua
db.table2.find({},{name:1,address:1})
db.table2.find({name:'zhangsan'},{name:1,age:1,address:1,by:1})
(6)and操作
逗号链接,
Lua
db.table2.find({name:'zhangsan',age:"lisi"},{name:1,age:1,address:1})
select name,age,address from table2 where name = "zhangsan" and age = "lisi"
(7)or操作
需要在条件前加$or
Lua
db.table2.find({$or:[{age:"lisi"},{address:"xuzhou"}]},{name:1,age:1,address:1})
(8)大于小于,等于操作
Lua
db.table2.find({age:{$gte:11,$lte:100}})
(9)in,not in
Lua
db.table2.find({age:{$in:[10,15,20,18,12]}})
(10)查询空值
Lua
db.table2.find({age:null})
(11)匹配查询
Lua
// 以zha开头的相当于like"zha%
db.table2.find({name:/^zha/})
// 相当于like"%zha%
db.table2.find({name:/zha/})
(12)使用distinct去重
Lua
db.table2.distinct('name')
// 相当于select distinct(name) from table2
(13)查询集合中的文档数
Lua
db.table2.count()
四.aggregate() 聚合操作
整个聚合的过程称为管道,由多个步骤构成。一个一个的管道,也就是聚合的步骤,上一个管道操作的结果可以作为下一个管道的初始数据。每一个中间结果都是一个{}
一个管道操作由2分布构成,管道操作,聚合表达式处理 。
<1>管道操作如下:
- $group:将集合中的文档分组,用于统计结果,_id键对应的值是根据什么分组
- **match**:用于过滤数据,只输出复合条件的文档,match使用MongoDB的标准查询操作,相当于where,having条件来过滤数据的
- $project:修改输入文档的结构,可以用来重命名,增加或删除域,也用于创建计算结果以及嵌套文档。 简单来说选择显示哪些元素,0代表不显示,1代表显示
- $limit:用来限制MongoDB聚合管道返回的文档数
- $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。 $sort:将输入的文档排序后输出,1是升序排序,-1是降序排序
- **$unwind:**将文档中的某个数组类型字段拆分成多条,产生多个文档,每条包含数组中的一个值
<2>聚合表达式:
- **$sum:**计算总和
- **$avg:**计算平均值
- **$min:**获取集合中所有文档对应值的最小值
- **$max:**获取集合中所有文档对应值的最大值
- **$push:**在结果文档中插入值到一个数组中
- **$first:**根据资源文档的排序获取第一个文档数据
- **$last:**根据资源文档的排序获取最后一个文档数据
语法:一个大括号表示一个管道处理{}
Lua
db.集合名称.aggregate([
{管道操作1:{表达式处理1}},
{管道操作2:{表达式处理1}},
{......}])
<3>通过实例讲清楚,直接看代码:
<4>准备数据
Lua
db.persons.insertMany([
{
name:"zhangsan",
gender:"man",
high:180,
weight:75,
salary:5800,
hobby:["basketball","music","money"]
},
{
name:"lisi",
gender:"man",
high:175,
weight:70,
salary:6000,
hobby:["run","music","money"]
},
{
name:"wangwu",
gender:"man",
high:178,
weight:73,
salary:6800,
hobby:["video","football","money"]
},
{
name:"zhaoliu",
gender:"man",
high:160,
weight:70,
salary:8000,
hobby:["video","football","money"]
},
{
name:"lili",
gender:"woman",
high:160,
weight:60,
salary:5000,
hobby:["video","money"]
},
{
name:"lingling",
gender:"woman",
high:165,
weight:63,
salary:6000,
hobby:["video","music"]
},
{
name:"jingjing",
gender:"woman",
high:158,
weight:58,
salary:5500,
hobby:["music","book","run"]
},
{
name:"cuicui",
gender:"man",
high:178,
weight:80,
salary:9500,
hobby:["video","football","money"]
},
{
name:"xiaohei",
gender:"man",
high:183,
weight:85,
salary:6800,
hobby:["football","money"]
}
])
<5>查询案例以及语句,共12个
注意点:
- $sum:1 是文档中出现一个符合条件的就+1
- 最外部的每个{}是一个管道操作,都需要加,_id是根据什么来分组,里面再由处理表达式具体处理,别忘记加
- value取值的时候:"name",别忘记加
- 注意value为0,1的操作
Lua
// 1.统计出男女生的人数
db.persons.aggregate([
{
$group:{
// _id是根据什么来分组
_id:"$gender",
// 对性别进行分组,根据每一组符合条件的出现一个文档+1,
counter:{$sum:1}
}
}
])
// 2.统计出男女生身高总数
db.persons.aggregate([
{
$group:{
_id:"$gender",
// 对每一组的符合条件的进行求和
counter:{$sum:"$high"}
}
}
])
// 3.统计出男女生平均身高
db.persons.aggregate([
{
$group:{
_id:"$gender",
counter:{$avg:"$high"}
}
}
])
// 4.分别找出男女生第一个出现的人的身高
db.persons.aggregate([
{
$group:{
_id:"$gender",
firster:{
$first:"$high"
}
}
}
])
db.persons.find()
// 5.分别找出男女生最后一个出现的人的身高,$first,$last,只关注的是每组的第一个,最后一个
db.persons.aggregate([
{
$group:{
_id:"$gender",
laster:{
$last:"$high"
}
}
}
])
// 6.分别找出男女生最高的身高
db.persons.aggregate([
{
$group:{
_id:"$gender",
highest:{
$max:"$high"
}
}
}
])
// 7.分别找出男女生最矮的身高
db.persons.aggregate([
{
$group:{
_id:"$gender",
lowest:{
$min:"$high"
}
}
}
])
// 8.按照男女生分类将身高分别放在数组中
db.persons.aggregate([
{
$group:{
_id:"$gender",
arr:{
$push:"$high"
}
}
}
])
// 9.查询身高>160的男女生人数
db.persons.aggregate([
{
$match:{
high:{
$gt:160
}
}
},
{
$group:{
_id:"$gender",
counter:{
$sum:1
}
}
}
])
db.persons.find()
// 10.查询身高>160的男女生人数,只输出人数,限制输出的字段,$project,限制查询字段,0是不输出的字段,1是输出字段
db.persons.aggregate([
{
$match:{
// high:属性的字段
high:{
$gt:160
}
}
},
{
$group:{
_id:"$gender",
counter:{$sum:1}
}
},
{
$project:{
_id:0,
counter:1
}
}
])
// 11.将男女生的人数排序输出,counter:1是正序输出,-1是倒序输出
db.persons.aggregate([
{
$group:{
_id:"$gender",
counter:{$sum:1}
}
},
{
$sort:{
counter:-1
}
},
{
$project:{
_id:0,
counter:1
}
}
])
// 12.对男生按照身高进行排序,输出3到5名的姓名和身高
db.persons.aggregate([
{
$match:{
gender:"man"
}
},
{
$sort:{
high:1
}
},
{
$skip:2
},
{
$limit:3
},
{
// 选择显示哪些元素,0代表不显示,1代表显示
$project:{
_id:0,
name:1,
high:1
}
}
])
ok,基本上敲完就知道MongoDB的聚合查询咋回事了