目录
mongoDB的常用操作符
mongoDB的聚合管道符号
比较操作符
逻辑运算符
数学运算符
mongoDB案例
插入测试数据
mongodb的阶段操作符号
关联查询
springBoot整合mongoDB
pom依赖
yml配置
java代码案例
mongoDB的常用操作符
mongoDB的聚合管道符号
| db.collection.aggregate( [ { | 使用aggregate()方法来构建和使用聚合管道。 |
比较操作符
$eq “=” 等于 $gt “>” 大于$gte ”>=“ 大于等于$lt “<” 小于$lte ”<= “小于等于$ne ”!=" 不等于$in 相当于MySQL的in$nin 相当于MySQL的nin
案例:db..find({ : { $gt: } })
逻辑运算符
$or OR或相当于MySQL的OR
案例:
db..find({$or:[{:{$lt:}},{:}], :})
limit 跳过指定数量的文档
skip 查询指定数量的文档
案例:
db..find({}).skip(20).limlit(20)
数学运算符
$add 加法 $subtract 减法$multiply 乘法$divide 除法$mod 求余
$eq “=” 等于 $gt “>” 大于$gte ”>=“ 大于等于$lt “<” 小于$lte ”<= “小于等于$ne ”!=" 不等于$in 相当于MySQL的in$nin 相当于MySQL的nin
案例:db.
$or OR或相当于MySQL的OR
案例:
db.
.find({$or:[{ :{$lt: }},{ : }], : })
limit 跳过指定数量的文档
skip 查询指定数量的文档
案例:
db.
.find({}).skip(20).limlit(20)
数学运算符
$add 加法 $subtract 减法$multiply 乘法$divide 除法$mod 求余
$add 加法 $subtract 减法$multiply 乘法$divide 除法$mod 求余
mongoDB案例
插入测试数据
db.student22.insertMany([{
"name": "张0",
"gender": "女",
"age": 0,
"math": NumberInt(84),
"language":NumberInt(99),
"classes": "一年级二班",
"Hobby": [ "蓝色", "蓝色1", "蓝色2" ]
},{
"name": "张1",
"gender": "男",
"age": 1,
"math": NumberInt(42),
"language": NumberInt(48),
"classes": "一年级二班",
"Hobby": [ "绿色", "绿色1", "绿色2" ]
},{
"name": "张2",
"gender": "女",
"age": 2,
"math": NumberInt(71),
"language": NumberInt(33),
"classes": "一年级一班",
"Hobby": ["青色", "青色1", "青色2" ]
},{
"name": "张3",
"gender": "男",
"age": 3,
"math": NumberInt(93),
"language": NumberInt(2),
"classes": "一年级一班",
"Hobby": [ "黄色", "黄色1","黄色2"]
}])
mongodb的阶段操作符号
所用的案例都是用的上面插入的数据
$match:
格式: {$match:}
介绍: 指定某个字段的查询条件,相当于MySQL中的 where
案例:
筛选math大于30,language小于100的信息
//可以结合上面的比较运算符,数学运算符,逻辑运算符操作
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}}
])
-------------------------------------------------------------------------------------------------------------------------
$count
格式: {$count : }
介绍: 返回总条数; 等价于MySQL中的count函数
案例:
筛选math大于30,language小于100的总记录数
db.student22.aggregate([
{$match:{classes:"一年级一班",math:{$gt:60},language:{$lt:80}}},
{$count:"name"}
])
-------------------------------------------------------------------------------------------------------------------------
$group
格式:
{$group:{_id:, : { : }} }
介绍:
使用该阶段符分组查询
该运算符必须是以下累加器运算符之一 (案例中有介绍)
字段名称前加一个美元符号$并用引号引起来
案例:
筛选math大于30,language小于100的记录, 根据classes字段分组查询,求出每个分组math字段的和.
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}}, //$sum:1 则会返回每个分组的总记录数
{$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
])
-------------------------------------------------------------------------------------------------------------------------
$project
格式: {$project:}
介绍: 指定哪些字段进入下阶段管道,或者返回。0:false ,1:true
案例:
接着上面的分组案例往下来,我们排除name和gender字段不接收
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}},
{$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
{$project:{name:0,gender:0}} //字段:0 表示排除他
])
-------------------------------------------------------------------------------------------------------------------------
$addFields
格式: {$addFields::}
介绍:
将新字段添加到文档。$addFields输出包含输入文档中所有现有字段
和新添加的字段的文档 . 字段名称前加一个美元符号$并用引号引起来
案例:
新加一个nowField字段.并且为每组的总分(mathCount字段)加1
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}},
{$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
{$project:{name:0,gender:0}},
//每个条记录都会增加nowField这个文档, 每条记录的mathCount都会加1
{$addFields:{nowField:"我是新加的字段",mathCount:{$add:["$mathCount",1]}}}
])
-------------------------------------------------------------------------------------------------------------------------
$set
格式: {$set::}
介绍:
将新字段添加到文档。$set输出包含输入文档中所有现有字段和新添加的字段的文档。
$set 和 $addFields这两个阶段等效于一个$project阶段.
字段名称前加一个美元符号$并用引号引起来
-------------------------------------------------------------------------------------------------------------------------
$redact
格式: { $redact: }
介绍:
根据条件限制文档的内容。
案例:
跟着上面的案例继续聚合, 使用$redact符筛选出mathCount字段大于160的数据
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}},
{$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
{$project:{name:0,gender:0}},
{$addFields:{nowField:"我是新建的字段",mathCount:{$add:["$mathCount",1]}}},
{$redact:{
$cond:{
if:{
$gt:["$mathCount",160]},
then:"$$KEEP",
else:"$$PRUNE"
}}}
])
-------------------------------------------------------------------------------------------------------------------------
$lookup
格式:
{
$lookup:
{
from: ,
localField: ,
foreignField: ,
as:
介绍:
关联查询
使用该操作符实现表之间的关联查询
案例:
//插入parent22表,与上面的student22表关联,
//关联的字段是name,关联的字段名可以不同,但是值必须相同,丛主表关联的字段类型必须相同(除数组类型外)
db.parent22.insertMany([
{name:"张0",mobile:1304444444,parentName:"张0的爸爸"},
{name:"张1",mobile:1374444444,parentName:"张1的爸爸"},
{name:"张0",mobile:1594444444,parentName:"张0的妈妈"},
{name:"张1",mobile:1864444444,parentName:"张1的妈妈"},
])
//mongo查询案例
db.student22.aggregate([
{$lookup:{
from:"parent22", //关联从表的表名
localField:"name", //主表关联的字段
foreignField: "name", //从表关联的字段(从表类型也可以是数组).
as:"pr" //给结果起个别名
}
}
])
//java实现的案例
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void mongoTest(){
Aggregation aggregation = Aggregation.newAggregation(Aggregation.lookup("从表表名", "主表关联字段名", "从表关联字段", "结果起的别名"));
AggregationResults result = mongoTemplate.aggregate(aggregation, "你的表名", Test.class);
//获取结果
List mappedResults = result.getMappedResults();
}
//mongo查询返回的结果
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac95e"),
"name" : "张0",
"gender" : "女",
"age" : 4.0,
"math" : NumberInt(84),
"language" : NumberInt(99),
"classes" : "一年级二班",
"Hobby" : ["蓝色", "蓝色1", "蓝色2"],
"pr" : [
{
"_id" : ObjectId("623151398a0c4bd7d10ac962"),
"name" : "张0",
"mobile" : 1304444444.0,
"parentName" : "张0的爸爸"
},
{
"_id" : ObjectId("623151918a0c4bd7d10ac966"),
"name" : "张0",
"mobile" : 1304444444.0,
"parentName" : "张0的爸爸"
},
{
"_id" : ObjectId("623151918a0c4bd7d10ac968"),
"name" : "张0",
"mobile" : 1594444444.0,
"parentName" : "张0的妈妈"
}
]
}
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac95f"),
"name" : "张1",
"gender" : "男",
"age" : 1.0,
"math" : NumberInt(42),
"language" : NumberInt(48),
"classes" : "一年级二班",
"Hobby" : [
"绿色",
"绿色1",
"绿色2"
],
"pr" : [
{
"_id" : ObjectId("623151398a0c4bd7d10ac963"),
"name" : "张1",
"mobile" : 1374444444.0,
"parentName" : "张1的爸爸"
},
{
"_id" : ObjectId("623151918a0c4bd7d10ac967"),
"name" : "张1",
"mobile" : 1374444444.0,
"parentName" : "张1的爸爸"
},
{
"_id" : ObjectId("623151918a0c4bd7d10ac969"),
"name" : "张1",
"mobile" : 1864444444.0,
"parentName" : "张1的妈妈"
}
]
}
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac960"),
"name" : "张2",
"gender" : "女",
"age" : 2.0,
"math" : NumberInt(71),
"language" : NumberInt(33),
"classes" : "一年级一班",
"Hobby" : [
"青色",
"青色1",
"青色2"
],
"pr" : [
{
"_id" : ObjectId("623151398a0c4bd7d10ac964"),
"name" : "张2",
"mobile" : 1594444444.0,
"parentName" : "张2的爸爸"
}
]
}
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac961"),
"name" : "张3",
"gender" : "男",
"age" : 3.0,
"math" : NumberInt(93),
"language" : NumberInt(2),
"classes" : "一年级一班",
"Hobby" : [
"黄色",
"黄色1",
"黄色2"
],
"pr" : [
{
"_id" : ObjectId("623151398a0c4bd7d10ac965"),
"name" : "张3",
"mobile" : 1864444444.0,
"parentName" : "张3的爸爸"
}
]
}
-------------------------------------------------------------------------------------------------------------------------
$unwind
格式: {$unwind :}
介绍:
拆分数组,数组中的每个数据都会生成一条记录.
字段名称前加一个美元符号$并用引号引起来
案例:
查询name等于"张0"的记录,该记录中有个Hobby字段是数组类型,将该数组拆分
db.student22.aggregate([
{$match:{name:"张0"}},
{$unwind:"$Hobby"}
])
-------------------------------------------------------------------------------------------------------------------------
$geoNear
格式: {$geoNear:}
介绍:
指定经纬度点,从mongodb中查询,最近到最远的顺序输出文档。
案例:参考这里
-------------------------------------------------------------------------------------------------------------------------
$bucket
格式:
{
$bucket: {
groupBy: ,
boundaries: [ , , ... ],
default: ,
output: {
: { <$accumulator expression> },
: { <$accumulator expression> }
}
}
}
介绍:
根据自定义条件分组
案例:
根据年龄区间分组
db.student22.aggregate([
{$bucket:{
groupBy: "$age", //根据age字段分组
boundaries:[1,4], //年龄再1到4之间(左开右闭.包含1,不包含4)的分一个组
default: "Other", //没有达到条件的分一个组
output:{
"student22":{
$push:{
"age":"$age" //这里表示将分组后的所有年龄数组
}
}
}
}}
])
//对应的Java代码 -------------------------------------------------------------------------->
import org.springframework.data.mongodb.core.MongoTemplate;
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void mongoTest(){
Aggregation newAggregation = Aggregation.newAggregation(
Aggregation.bucket("age")
.withDefaultBucket("other")
.withBoundaries(1, 4)
.andOutput("age")
.push().as("student22")
);
AggregationResults result = mongoTemplate
.aggregate(newAggregation, "你的表名", 实体类.class);
//获取结果
List mappedResults = result.getMappedResults();
}
db.student22.insertMany([{
"name": "张0",
"gender": "女",
"age": 0,
"math": NumberInt(84),
"language":NumberInt(99),
"classes": "一年级二班",
"Hobby": [ "蓝色", "蓝色1", "蓝色2" ]
},{
"name": "张1",
"gender": "男",
"age": 1,
"math": NumberInt(42),
"language": NumberInt(48),
"classes": "一年级二班",
"Hobby": [ "绿色", "绿色1", "绿色2" ]
},{
"name": "张2",
"gender": "女",
"age": 2,
"math": NumberInt(71),
"language": NumberInt(33),
"classes": "一年级一班",
"Hobby": ["青色", "青色1", "青色2" ]
},{
"name": "张3",
"gender": "男",
"age": 3,
"math": NumberInt(93),
"language": NumberInt(2),
"classes": "一年级一班",
"Hobby": [ "黄色", "黄色1","黄色2"]}])
mongodb的阶段操作符号
所用的案例都是用的上面插入的数据
$match:
格式: {$match:}
介绍: 指定某个字段的查询条件,相当于MySQL中的 where
案例:
筛选math大于30,language小于100的信息
//可以结合上面的比较运算符,数学运算符,逻辑运算符操作
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}}
])
-------------------------------------------------------------------------------------------------------------------------
$count
格式: {$count : }
介绍: 返回总条数; 等价于MySQL中的count函数
案例:
筛选math大于30,language小于100的总记录数
db.student22.aggregate([
{$match:{classes:"一年级一班",math:{$gt:60},language:{$lt:80}}},
{$count:"name"}
])
-------------------------------------------------------------------------------------------------------------------------
$group
格式:
{$group:{_id:, : { : }} }
介绍:
使用该阶段符分组查询
该运算符必须是以下累加器运算符之一 (案例中有介绍)
字段名称前加一个美元符号$并用引号引起来
案例:
筛选math大于30,language小于100的记录, 根据classes字段分组查询,求出每个分组math字段的和.
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}}, //$sum:1 则会返回每个分组的总记录数
{$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
])
-------------------------------------------------------------------------------------------------------------------------
$project
格式: {$project:}
介绍: 指定哪些字段进入下阶段管道,或者返回。0:false ,1:true
案例:
接着上面的分组案例往下来,我们排除name和gender字段不接收
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}},
{$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
{$project:{name:0,gender:0}} //字段:0 表示排除他
])
-------------------------------------------------------------------------------------------------------------------------
$addFields
格式: {$addFields::}
介绍:
将新字段添加到文档。$addFields输出包含输入文档中所有现有字段
和新添加的字段的文档 . 字段名称前加一个美元符号$并用引号引起来
案例:
新加一个nowField字段.并且为每组的总分(mathCount字段)加1
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}},
{$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
{$project:{name:0,gender:0}},
//每个条记录都会增加nowField这个文档, 每条记录的mathCount都会加1
{$addFields:{nowField:"我是新加的字段",mathCount:{$add:["$mathCount",1]}}}
])
-------------------------------------------------------------------------------------------------------------------------
$set
格式: {$set::}
介绍:
将新字段添加到文档。$set输出包含输入文档中所有现有字段和新添加的字段的文档。
$set 和 $addFields这两个阶段等效于一个$project阶段.
字段名称前加一个美元符号$并用引号引起来
-------------------------------------------------------------------------------------------------------------------------
$redact
格式: { $redact: }
介绍:
根据条件限制文档的内容。
案例:
跟着上面的案例继续聚合, 使用$redact符筛选出mathCount字段大于160的数据
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}},
{$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
{$project:{name:0,gender:0}},
{$addFields:{nowField:"我是新建的字段",mathCount:{$add:["$mathCount",1]}}},
{$redact:{
$cond:{
if:{
$gt:["$mathCount",160]},
then:"$$KEEP",
else:"$$PRUNE"
}}}
])
-------------------------------------------------------------------------------------------------------------------------
$lookup
格式:
{
$lookup:
{
from: ,
localField: ,
foreignField: ,
as:
介绍:
关联查询
使用该操作符实现表之间的关联查询
案例:
//插入parent22表,与上面的student22表关联,
//关联的字段是name,关联的字段名可以不同,但是值必须相同,丛主表关联的字段类型必须相同(除数组类型外)
db.parent22.insertMany([
{name:"张0",mobile:1304444444,parentName:"张0的爸爸"},
{name:"张1",mobile:1374444444,parentName:"张1的爸爸"},
{name:"张0",mobile:1594444444,parentName:"张0的妈妈"},
{name:"张1",mobile:1864444444,parentName:"张1的妈妈"},
])
//mongo查询案例
db.student22.aggregate([
{$lookup:{
from:"parent22", //关联从表的表名
localField:"name", //主表关联的字段
foreignField: "name", //从表关联的字段(从表类型也可以是数组).
as:"pr" //给结果起个别名
}
}
])
//java实现的案例
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void mongoTest(){
Aggregation aggregation = Aggregation.newAggregation(Aggregation.lookup("从表表名", "主表关联字段名", "从表关联字段", "结果起的别名"));
AggregationResults result = mongoTemplate.aggregate(aggregation, "你的表名", Test.class);
//获取结果
List mappedResults = result.getMappedResults();
}
//mongo查询返回的结果
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac95e"),
"name" : "张0",
"gender" : "女",
"age" : 4.0,
"math" : NumberInt(84),
"language" : NumberInt(99),
"classes" : "一年级二班",
"Hobby" : ["蓝色", "蓝色1", "蓝色2"],
"pr" : [
{
"_id" : ObjectId("623151398a0c4bd7d10ac962"),
"name" : "张0",
"mobile" : 1304444444.0,
"parentName" : "张0的爸爸"
},
{
"_id" : ObjectId("623151918a0c4bd7d10ac966"),
"name" : "张0",
"mobile" : 1304444444.0,
"parentName" : "张0的爸爸"
},
{
"_id" : ObjectId("623151918a0c4bd7d10ac968"),
"name" : "张0",
"mobile" : 1594444444.0,
"parentName" : "张0的妈妈"
}
]
}
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac95f"),
"name" : "张1",
"gender" : "男",
"age" : 1.0,
"math" : NumberInt(42),
"language" : NumberInt(48),
"classes" : "一年级二班",
"Hobby" : [
"绿色",
"绿色1",
"绿色2"
],
"pr" : [
{
"_id" : ObjectId("623151398a0c4bd7d10ac963"),
"name" : "张1",
"mobile" : 1374444444.0,
"parentName" : "张1的爸爸"
},
{
"_id" : ObjectId("623151918a0c4bd7d10ac967"),
"name" : "张1",
"mobile" : 1374444444.0,
"parentName" : "张1的爸爸"
},
{
"_id" : ObjectId("623151918a0c4bd7d10ac969"),
"name" : "张1",
"mobile" : 1864444444.0,
"parentName" : "张1的妈妈"
}
]
}
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac960"),
"name" : "张2",
"gender" : "女",
"age" : 2.0,
"math" : NumberInt(71),
"language" : NumberInt(33),
"classes" : "一年级一班",
"Hobby" : [
"青色",
"青色1",
"青色2"
],
"pr" : [
{
"_id" : ObjectId("623151398a0c4bd7d10ac964"),
"name" : "张2",
"mobile" : 1594444444.0,
"parentName" : "张2的爸爸"
}
]
}
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac961"),
"name" : "张3",
"gender" : "男",
"age" : 3.0,
"math" : NumberInt(93),
"language" : NumberInt(2),
"classes" : "一年级一班",
"Hobby" : [
"黄色",
"黄色1",
"黄色2"
],
"pr" : [
{
"_id" : ObjectId("623151398a0c4bd7d10ac965"),
"name" : "张3",
"mobile" : 1864444444.0,
"parentName" : "张3的爸爸"
}
]
}
-------------------------------------------------------------------------------------------------------------------------
$unwind
格式: {$unwind :}
介绍:
拆分数组,数组中的每个数据都会生成一条记录.
字段名称前加一个美元符号$并用引号引起来
案例:
查询name等于"张0"的记录,该记录中有个Hobby字段是数组类型,将该数组拆分
db.student22.aggregate([
{$match:{name:"张0"}},
{$unwind:"$Hobby"}
])
-------------------------------------------------------------------------------------------------------------------------
$geoNear
格式: {$geoNear:}
介绍:
指定经纬度点,从mongodb中查询,最近到最远的顺序输出文档。
案例:参考这里
-------------------------------------------------------------------------------------------------------------------------
$bucket
格式:
{
$bucket: {
groupBy: ,
boundaries: [ , , ... ],
default: ,
output: {
: { <$accumulator expression> },
: { <$accumulator expression> }
}
}
}
介绍:
根据自定义条件分组
案例:
根据年龄区间分组
db.student22.aggregate([
{$bucket:{
groupBy: "$age", //根据age字段分组
boundaries:[1,4], //年龄再1到4之间(左开右闭.包含1,不包含4)的分一个组
default: "Other", //没有达到条件的分一个组
output:{
"student22":{
$push:{
"age":"$age" //这里表示将分组后的所有年龄数组
}
}
}
}}
])
//对应的Java代码 -------------------------------------------------------------------------->
import org.springframework.data.mongodb.core.MongoTemplate;
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void mongoTest(){
Aggregation newAggregation = Aggregation.newAggregation(
Aggregation.bucket("age")
.withDefaultBucket("other")
.withBoundaries(1, 4)
.andOutput("age")
.push().as("student22")
);
AggregationResults result = mongoTemplate
.aggregate(newAggregation, "你的表名", 实体类.class);
//获取结果
List mappedResults = result.getMappedResults();
}
所用的案例都是用的上面插入的数据
$match:
格式: {$match:
介绍: 指定某个字段的查询条件,相当于MySQL中的 where
案例:
筛选math大于30,language小于100的信息
//可以结合上面的比较运算符,数学运算符,逻辑运算符操作
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}}
])
-------------------------------------------------------------------------------------------------------------------------
$count
格式: {$count :
介绍: 返回总条数; 等价于MySQL中的count函数
案例:
筛选math大于30,language小于100的总记录数
db.student22.aggregate([
{$match:{classes:"一年级一班",math:{$gt:60},language:{$lt:80}}},
{$count:"name"}
])
-------------------------------------------------------------------------------------------------------------------------
$group
格式:
{$group:{_id:
介绍:
使用该阶段符分组查询
该
字段名称前加一个美元符号$并用引号引起来
案例:
筛选math大于30,language小于100的记录, 根据classes字段分组查询,求出每个分组math字段的和.
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}}, //$sum:1 则会返回每个分组的总记录数
{$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
])
-------------------------------------------------------------------------------------------------------------------------
$project
格式: {$project:
介绍: 指定哪些字段进入下阶段管道,或者返回。0:false ,1:true
案例:
接着上面的分组案例往下来,我们排除name和gender字段不接收
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}},
{$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
{$project:{name:0,gender:0}} //字段:0 表示排除他
])
-------------------------------------------------------------------------------------------------------------------------
$addFields
格式: {$addFields:
介绍:
将新字段添加到文档。$addFields输出包含输入文档中所有现有字段
和新添加的字段的文档 . 字段名称前加一个美元符号$并用引号引起来
案例:
新加一个nowField字段.并且为每组的总分(mathCount字段)加1
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}},
{$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
{$project:{name:0,gender:0}},
//每个条记录都会增加nowField这个文档, 每条记录的mathCount都会加1
{$addFields:{nowField:"我是新加的字段",mathCount:{$add:["$mathCount",1]}}}
])
-------------------------------------------------------------------------------------------------------------------------
$set
格式: {$set:
介绍:
将新字段添加到文档。$set输出包含输入文档中所有现有字段和新添加的字段的文档。
$set 和 $addFields这两个阶段等效于一个$project阶段.
字段名称前加一个美元符号$并用引号引起来
-------------------------------------------------------------------------------------------------------------------------
$redact
格式: { $redact:
介绍:
根据条件限制文档的内容。
案例:
跟着上面的案例继续聚合, 使用$redact符筛选出mathCount字段大于160的数据
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}},
{$group:{_id:"$classes",mathCount:{$sum:"$math"},id:{$last:"$_id"},name:{$last:"$name"},gender:{$first:"$gender"}}},
{$project:{name:0,gender:0}},
{$addFields:{nowField:"我是新建的字段",mathCount:{$add:["$mathCount",1]}}},
{$redact:{
$cond:{
if:{
$gt:["$mathCount",160]},
then:"$$KEEP",
else:"$$PRUNE"
}}}
])
-------------------------------------------------------------------------------------------------------------------------
$lookup
格式:
{
$lookup:
{
from: ,
localField: ,
foreignField: ,
as:
介绍:
关联查询
使用该操作符实现表之间的关联查询
案例:
//插入parent22表,与上面的student22表关联,
//关联的字段是name,关联的字段名可以不同,但是值必须相同,丛主表关联的字段类型必须相同(除数组类型外)
db.parent22.insertMany([
{name:"张0",mobile:1304444444,parentName:"张0的爸爸"},
{name:"张1",mobile:1374444444,parentName:"张1的爸爸"},
{name:"张0",mobile:1594444444,parentName:"张0的妈妈"},
{name:"张1",mobile:1864444444,parentName:"张1的妈妈"},
])
//mongo查询案例
db.student22.aggregate([
{$lookup:{
from:"parent22", //关联从表的表名
localField:"name", //主表关联的字段
foreignField: "name", //从表关联的字段(从表类型也可以是数组).
as:"pr" //给结果起个别名
}
}
])
//java实现的案例
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void mongoTest(){
Aggregation aggregation = Aggregation.newAggregation(Aggregation.lookup("从表表名", "主表关联字段名", "从表关联字段", "结果起的别名"));
AggregationResults result = mongoTemplate.aggregate(aggregation, "你的表名", Test.class);
//获取结果
List mappedResults = result.getMappedResults();
}
//mongo查询返回的结果
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac95e"),
"name" : "张0",
"gender" : "女",
"age" : 4.0,
"math" : NumberInt(84),
"language" : NumberInt(99),
"classes" : "一年级二班",
"Hobby" : ["蓝色", "蓝色1", "蓝色2"],
"pr" : [
{
"_id" : ObjectId("623151398a0c4bd7d10ac962"),
"name" : "张0",
"mobile" : 1304444444.0,
"parentName" : "张0的爸爸"
},
{
"_id" : ObjectId("623151918a0c4bd7d10ac966"),
"name" : "张0",
"mobile" : 1304444444.0,
"parentName" : "张0的爸爸"
},
{
"_id" : ObjectId("623151918a0c4bd7d10ac968"),
"name" : "张0",
"mobile" : 1594444444.0,
"parentName" : "张0的妈妈"
}
]
}
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac95f"),
"name" : "张1",
"gender" : "男",
"age" : 1.0,
"math" : NumberInt(42),
"language" : NumberInt(48),
"classes" : "一年级二班",
"Hobby" : [
"绿色",
"绿色1",
"绿色2"
],
"pr" : [
{
"_id" : ObjectId("623151398a0c4bd7d10ac963"),
"name" : "张1",
"mobile" : 1374444444.0,
"parentName" : "张1的爸爸"
},
{
"_id" : ObjectId("623151918a0c4bd7d10ac967"),
"name" : "张1",
"mobile" : 1374444444.0,
"parentName" : "张1的爸爸"
},
{
"_id" : ObjectId("623151918a0c4bd7d10ac969"),
"name" : "张1",
"mobile" : 1864444444.0,
"parentName" : "张1的妈妈"
}
]
}
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac960"),
"name" : "张2",
"gender" : "女",
"age" : 2.0,
"math" : NumberInt(71),
"language" : NumberInt(33),
"classes" : "一年级一班",
"Hobby" : [
"青色",
"青色1",
"青色2"
],
"pr" : [
{
"_id" : ObjectId("623151398a0c4bd7d10ac964"),
"name" : "张2",
"mobile" : 1594444444.0,
"parentName" : "张2的爸爸"
}
]
}
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac961"),
"name" : "张3",
"gender" : "男",
"age" : 3.0,
"math" : NumberInt(93),
"language" : NumberInt(2),
"classes" : "一年级一班",
"Hobby" : [
"黄色",
"黄色1",
"黄色2"
],
"pr" : [
{
"_id" : ObjectId("623151398a0c4bd7d10ac965"),
"name" : "张3",
"mobile" : 1864444444.0,
"parentName" : "张3的爸爸"
}
]
}
-------------------------------------------------------------------------------------------------------------------------
$unwind
格式: {$unwind :
介绍:
拆分数组,数组中的每个数据都会生成一条记录.
字段名称前加一个美元符号$并用引号引起来
案例:
查询name等于"张0"的记录,该记录中有个Hobby字段是数组类型,将该数组拆分
db.student22.aggregate([
{$match:{name:"张0"}},
{$unwind:"$Hobby"}
])
-------------------------------------------------------------------------------------------------------------------------
$geoNear
格式: {$geoNear:
介绍:
指定经纬度点,从mongodb中查询,最近到最远的顺序输出文档。
案例:参考这里
-------------------------------------------------------------------------------------------------------------------------
$bucket
格式:
{
$bucket: {
groupBy: ,
boundaries: [ , , ... ],
default: ,
output: {
: { <$accumulator expression> },
: { <$accumulator expression> }
}
}
}
介绍:
根据自定义条件分组
案例:
根据年龄区间分组
db.student22.aggregate([
{$bucket:{
groupBy: "$age", //根据age字段分组
boundaries:[1,4], //年龄再1到4之间(左开右闭.包含1,不包含4)的分一个组
default: "Other", //没有达到条件的分一个组
output:{
"student22":{
$push:{
"age":"$age" //这里表示将分组后的所有年龄数组
}
}
}
}}
])
//对应的Java代码 -------------------------------------------------------------------------->
import org.springframework.data.mongodb.core.MongoTemplate;
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void mongoTest(){
Aggregation newAggregation = Aggregation.newAggregation(
Aggregation.bucket("age")
.withDefaultBucket("other")
.withBoundaries(1, 4)
.andOutput("age")
.push().as("student22")
);
AggregationResults result = mongoTemplate
.aggregate(newAggregation, "你的表名", 实体类.class);
//获取结果
List mappedResults = result.getMappedResults();
}
springBoot整合mongoDB
pom依赖
org.springframework.boot
spring-boot-starter-data-mongodb
yml配置
spring:
data:
mongodb:
uri: mongodb://用户名:密码@IP:端口/数据库名字?authSource=admin&authMechanism=SCRAM-SHA-1
java代码案例
@Autowired
private MongoTemplate mongoTemplate;
public void mongoTest(){
ConditionalOperators.Cond condition = ConditionalOperators.Cond.when((Criteria.where("表中的字段名1").is("等于的值"))).thenValueOf("").otherwisevalueOf("");
//在这里构造我们的聚合条件
Aggregation aggregation = Aggregation.newAggregation(
//根据自己的业务构造自己的条件
Aggregation.match(Criteria.where("表中的字段名1").is("等于的值").and("表中的字段名2").in("等于的值")),
Aggregation.group("要分组的字段名").first("表中的字段名").as("起的别名"),
Aggregation.project().andExclude("排除的字段").andInclude("包含的字段"),
Aggregation.addFields().addField("nowField").withValue("新建的字段").build().and().addField().withValueOfexpression("a", 1, 2).build(),
Aggregation.unwind("表中数组字段名"),
Aggregation.redact(condition)
);
//查询
AggregationResults result = mongoTemplate.aggregate(aggregation, "你的表名", Test.class);
//获取结果
List mappedResults = result.getMappedResults();
}
org.springframework.boot spring-boot-starter-data-mongodb
yml配置
spring:
data:
mongodb:
uri: mongodb://用户名:密码@IP:端口/数据库名字?authSource=admin&authMechanism=SCRAM-SHA-1
java代码案例
@Autowired
private MongoTemplate mongoTemplate;
public void mongoTest(){
ConditionalOperators.Cond condition = ConditionalOperators.Cond.when((Criteria.where("表中的字段名1").is("等于的值"))).thenValueOf("").otherwisevalueOf("");
//在这里构造我们的聚合条件
Aggregation aggregation = Aggregation.newAggregation(
//根据自己的业务构造自己的条件
Aggregation.match(Criteria.where("表中的字段名1").is("等于的值").and("表中的字段名2").in("等于的值")),
Aggregation.group("要分组的字段名").first("表中的字段名").as("起的别名"),
Aggregation.project().andExclude("排除的字段").andInclude("包含的字段"),
Aggregation.addFields().addField("nowField").withValue("新建的字段").build().and().addField().withValueOfexpression("a", 1, 2).build(),
Aggregation.unwind("表中数组字段名"),
Aggregation.redact(condition)
);
//查询
AggregationResults result = mongoTemplate.aggregate(aggregation, "你的表名", Test.class);
//获取结果
List mappedResults = result.getMappedResults();
}
spring:
data:
mongodb:
uri: mongodb://用户名:密码@IP:端口/数据库名字?authSource=admin&authMechanism=SCRAM-SHA-1
@Autowired
private MongoTemplate mongoTemplate;
public void mongoTest(){
ConditionalOperators.Cond condition = ConditionalOperators.Cond.when((Criteria.where("表中的字段名1").is("等于的值"))).thenValueOf("").otherwisevalueOf("");
//在这里构造我们的聚合条件
Aggregation aggregation = Aggregation.newAggregation(
//根据自己的业务构造自己的条件
Aggregation.match(Criteria.where("表中的字段名1").is("等于的值").and("表中的字段名2").in("等于的值")),
Aggregation.group("要分组的字段名").first("表中的字段名").as("起的别名"),
Aggregation.project().andExclude("排除的字段").andInclude("包含的字段"),
Aggregation.addFields().addField("nowField").withValue("新建的字段").build().and().addField().withValueOfexpression("a", 1, 2).build(),
Aggregation.unwind("表中数组字段名"),
Aggregation.redact(condition)
);
//查询
AggregationResults result = mongoTemplate.aggregate(aggregation, "你的表名", Test.class);
//获取结果
List mappedResults = result.getMappedResults();
}



