目录
mongoDB的常用操作符
mongoDB的聚合管道符号
比较操作符
逻辑运算符
注意坑
数学运算符
mongoDB案例
插入测试数据
mongodb的阶段操作符号
$match:
$count
$group
$replaceRoot
$project
$addFields
$sort
$set
$redact
$lookup
关联查询
$unwind
$geoNear
$bucket
springBoot整合mongoDB
pom依赖
yml配置
java代码案例
Java操作MongoDB技巧:
mongoDB的常用操作符
mongoDB的聚合管道符号
db.collection.aggregate( [ { <stage> }, ... ] ) | 使用aggregate()方法来构建和使用聚合管道。 |
比较操作符
- $eq “=” 等于
- $gt “>” 大于
- $gte ”>=“ 大于等于
- $lt “<” 小于
- $lte ”<= “小于等于
- $ne ”!=" 不等于
- $in 相当于MySQL的in
- $nin 相当于MySQL的nin
案例:db.<CollectionName>.find({ <field>: { $gt: <value> } })
逻辑运算符
- $or OR或相当于MySQL的OR
案例:
db.<CollectionName>.find({$or:[{<field>:{$lt:<value>}},{<field>:<value>}], <field>:<value>})
- limit 跳过指定数量的文档
- skip 查询指定数量的文档
案例:
db.<CollectionName>.find({}).skip(20).limlit(20)
注意坑
1. 区间查询
$and逻辑符号,这样查询;
正确案例:
db.<CollectionName>.find({$and[{age:{$gte:30}},{age:{$lte:60}}]})
或者:
db.<CollectionName>.find({age:{$gte:30,$lte:60}})
错误案例:(这种他不是区间查询,第二个条件会覆盖掉第一个条件)
db.<CollectionName>.find({age:{$gte:30},age:{$lte:60}})
2. NumberLong类型
Mongo的NumberLong长度超过19,查询要强转。
假如说我们age字段是NumberLong类型的。存入的数据超过19位,查询的需要强转一下,不然呢查询不到
正确案例:
db.heartBpmHistory.find({age:{$gte:NumberLong('30'),$lte:NumberLong('60')}})
错误案例一:
db.<CollectionName>.find({age:{$gte:30,$lte:60}})
错误案例二:
db.heartBpmHistory.find({age:{$gte:NumberLong(30),$lte:NumberLong(60)}})
数学运算符
- $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"]}])
下面的Java案例中关于mongodb操作的类皆来与
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.test.context.junit4.SpringRunner;
包中,请注意引包问题
mongodb的阶段操作符号
所用的案例都是用的上面插入的数据
$match:
field:value>}
介绍: 指定某个字段的查询条件,相当于MySQL中的 where
案例:
筛选math大于30,language小于100的信息
//可以结合上面的比较运算符,数学运算符,逻辑运算符操作
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}}
])
-------------------------------------------------------------------------------------------------------------------------
$count
field>}
介绍: 返回总条数; 等价于MySQL中的count函数
案例:
筛选math大于30,language小于100的总记录数
db.student22.aggregate([
{$match:{classes:"一年级一班",math:{$gt:60},language:{$lt:80}}},
{$count:"name"}
])
-------------------------------------------------------------------------------------------------------------------------
$group
格式:
Field>, <field1>: { <accumulator1> : <expression1> }} }
介绍:
使用该阶段符分组查询
该
<accumulator>
运算符必须是以下累加器运算符之一 (案例中有介绍)字段名称前加一个美元符号
$
并用引号引起来案例:
筛选math大于30,language小于100的记录, 根据classes字段分组查询,求出每个分组math字段的和.
//第一种方式,_id会被覆盖
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"}}},
])
//第二种id不会别覆盖的方式
db.student22.aggregate([
{$match:{math:{$gt:30},language:{$lt:100}}}, //$sum:1 则会返回每个分组的总记录数
{$group:{_id:"$classes",data:{$first:"$$ROOT"}}},
{$replaceRoot: { newRoot: "$data" }},
])
/** ---------------累加器运算符---------------------------------------------
$addToSet 返回每个组的唯一表达式值的数组。数组元素的顺序未定义。
$avg 返回数值的平均值。忽略非数字值。
$first 从每个组的第一个文档返回一个值。仅当文档按定义的顺序定义顺序。
$last 从每个组的最后一个文档返回一个值。仅当文档按定义的顺序定义顺序。
$max 返回每个组的最高表达式值。
$mergeObjects 返回通过组合每个组的输入文档而创建的文档。
$min 返回每个组的最低表达式值。
$push 返回每个组的表达式值数组。
$stdDevPop 返回输入值的总体标准偏差。
$stdDevSamp 返回输入值的样本标准偏差。
$sum 返回数值的总和。忽略非数字值。
**/
//java代码实现
@Autowired
private MongoTemplate mongoTemplate;
public void mongoGroupTest(){
Aggregation aggregation = Aggregation.newAggregation(
//先筛选
Aggregation.match(Criteria.where("math").gt(30).and("language").lt(100)),
//加入我们要娶每组中最大的一条记录,就可以先在这里倒叙,然后去第一天记录
Aggregation.sort(Sort.Direction.DESC,"排序字段"),
//在分组
Aggregation.group("classes").first("$$ROOT").as("data"),
//然后复原
Aggregation.replaceRoot().withValueOf("data")
);
//查询
AggregationResults<AttackSecurityEntity> aggregate = mongoTemplate.aggregate(aggregation, "你的表名", 实体类名.class);
List<AttackSecurityEntity> results = aggregate.getMappedResults();//获取数据
}
$replaceRoot
介绍:
将嵌套的数据提取出来,
replacementDocument>一定要是个对象字段,或者没有该字段都会报错
格式: { $replaceRoot: { newRoot: <replacementDocument> } }
案例:
//插入测试数据
db.demo10.insert({
name:"测试$replaceRoot符的数据",
data:{
id:NumberInt(123),
name:"张上",
age:NumberInt(12)
}
})
//demo01中嵌套了一个对象叫data,假如说我们的需求就只需要data对象,
//那么我们可以使用$replaceRoot阶段符号实现
//Mongo语句实现
db.demo10.aggregate( [
{ $replaceRoot: { newRoot: "$data" } }
] )
//Java案例在group案例中有实现
-------------------------------------------------------------------------------------------------------------------------
$project
field:0,field:1>}
介绍: 指定哪些字段进入下阶段管道,或者返回。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 表示排除他
])
//Java案例在文章末尾“java案例”中有写
-------------------------------------------------------------------------------------------------------------------------
$addFields
格式: {$addFields:<newField>:<value>}
介绍:
将新字段添加到文档。
$addFields
输出包含输入文档中所有现有字段和新添加的字段的文档 . 字段名称前加一个美元符号
$
并用引号引起来案例:
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]}}}
])
//Java案例在文章末尾“java案例”中有显示
-------------------------------------------------------------------------------------------------------------------------
$sort
格式: {$sort:{ <field1>: <sort order>, <field2>: <sort order> ... } }
介绍: 排序符, -1 表示倒叙, 1表示正序
案例:
为总分(mathCount字段) 倒叙排序.
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]}}},
{$sort:{mathCount:-1}}
])
//Java案例在文章末尾“java案例”中有显示
$set
格式: {$set:<newField>:<value>}
介绍:
将新字段添加到文档。
$set
输出包含输入文档中所有现有字段和新添加的字段的文档。$set 和 $addFields这两个阶段等效于一个$project阶段.
字段名称前加一个美元符号
$
并用引号引起来-------------------------------------------------------------------------------------------------------------------------
$redact
格式: { $redact: <expression> }
介绍:
根据条件限制文档的内容。
案例:
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"
}}}
])
/**then 和 else 可以是任何有效表达式,只要它解析为$$ DESCEND, $$ PRUNE或$$ KEEP系统变量即可。
$$ DESCEND : $redact返回当前文档级别的字段,不包括嵌入式文档。要将嵌入式文档和嵌入式文档包含在数组中,请将$cond 表达式应用于嵌入式文档,以确定对这些嵌入式文档的访问。
$$ KEEP: $redact返回或将所有字段保留在当前文档/嵌入式文档级别,而无需进一步检查此级别的字段。即使所包含的字段包含可能具有不同访问级别的嵌入式文档,这也适用。
$$PRUNE: $redact在当前文档/嵌入文档级别排除所有字段,而无需进一步检查任何排除的字段。即使排除字段包含具有不同访问级别的嵌入式文档,这也适用。
**/
//Java代码实现
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void mongoTest(){
//构造$redact的条件
ConditionalOperators.Cond cond = ConditionalOperators.Cond.when(ComparisonOperators.Gt.valueOf("mathCount").greaterThanValue(160)).then("$$KEEP").otherwise("$$PRUNE");
Aggregation aggregation = Aggregation.newAggregation(
//先筛选
Aggregation.match(Criteria.where("math").gt(30).and("language").lt(100)),
//在分组
Aggregation.group("classes").sum("$math").as("mathCount").last("_id").as("id").last("name").as("name"),
//追加字段
Aggregation.addFields().addField("nowField").withValue("我是新建的字段").addFieldWithValue("mathCount", ArithmeticOperators.Add.valueOf("mathCount").add(1)).build(),
//排除字段
Aggregation.project().andExclude("name","gender"),
Aggregation.redact(cond)
);
//查询
AggregationResults<AttackSecurityEntity> aggregate = mongoTemplate.aggregate(aggregation, "你的表名", 实体类名.class);
List<AttackSecurityEntity> results = aggregate.getMappedResults();
}
-------------------------------------------------------------------------------------------------------------------------
$lookup
格式:
{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
as: <output array field>
}
}
介绍:
关联查询
使用该操作符实现表之间的关联查询
案例:
//插入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关联查询案例 1
db.student22.aggregate([
{$lookup:{
from:"parent22", //关联从表的表名
localField:"name", //主表关联的字段
foreignField: "name", //从表关联的字段(从表类型也可以是数组).
as:"pr" //给结果起个别名
}
}
])
/*相当于MySQL的
select t.*,p.* from student22 as t,parent22 as p where t.name = p.name */
//java实现的案例
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void mongoTest(){
Aggregation aggregation =
Aggregation.newAggregation(
Aggregation.lookup(
"从表表名",
"主表关联字段名",
"从表关联字段",
"结果起的别名"));
AggregationResults<Test> result =
mongoTemplate.aggregate(aggregation, "你的表名", Test.class);
//获取结果
List<Test> mappedResults = result.getMappedResults();
}
--------------------------------------多条件关联查询案例--------------------------------
//mongo多条件关联查询案例 2
db.student22.aggregate([
{$lookup:{
from:"parent22", //关联从表的表名
let: {
// 主表用来要作为筛选条件的字段
Sname: "$name",
pName:"$parentName"
},
pipeline: [{
$match: {
name:{$eq:"张1"} // 筛选从表name字段等于‘张1’的信息
}
},
{
$match: {
$expr: { //也可以使用expr,在expr中写聚合表达式
// 表示筛选从表name字段和主表parentName字段相等的
$eq: ["$name","$$pName"]
}
}
}
//下面还可以继续指定其他管道阶段符合
],
as:"pr" //给结果起个别名
}
}
])
/*
mongodb多条件关联查询java案例:
看了很多文档和博客都没有找MongoTemplate关于操作lookup.let多条件关联查询的文档,
所以在java案例中使用MongoClient 代替 MongoTemplate 查询。
*/
import com.mongodb.client.MongoClient;
@Autowired
private MongoClient mongoClient;
public void lookupLetTest(){
Bson lookup = Aggregates.lookup(
"parent22", //关联从表的表名
Arrays.asList( // 用来要作为筛选条件的字段
new Variable<>("Sname", "$name"),
new Variable<>("pName", "$parentName")
),
Arrays.asList(
Aggregates.match(
Filters.eq("name","张1") // 筛选从表name等于‘张1’的信息,
),
Aggregates.match(
Filters.expr(
Filters.eq("$name","$$pName") // 筛选从表name等于主表parentName的信息
)
)
),
"pr" //给结果起个别名
);
AggregateIterable<Map> aggregate = mongoClient.
getDatabase("数据库名字").getCollection("表名字").aggregate(Arrays.asList(lookup), Map.class);
for (Map map : aggregate) {
}
}
//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 :<arrayField>}
介绍:
拆分数组,数组中的每个数据都会生成一条记录.
字段名称前加一个美元符号
$
并用引号引起来案例:
查询name等于"张0"的记录,该记录中有个Hobby字段是数组类型,将该数组拆分
db.student22.aggregate([
{$match:{name:"张0"}},
{$unwind:"$Hobby"}
])
/**
未拆分的数据:
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac95e"),
"name" : "张0",
"gender" : "女",
"age" : 0.0,
"math" : NumberInt(84),
"language" : NumberInt(99),
"classes" : "一年级二班",
"Hobby" : [
"蓝色",
"蓝色1",
"蓝色2"
]
}
拆分后的数据:
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac95e"),
"name" : "张0",
"gender" : "女",
"age" : 0.0,
"math" : NumberInt(84),
"language" : NumberInt(99),
"classes" : "一年级二班",
"Hobby" : "蓝色"
}
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac95e"),
"name" : "张0",
"gender" : "女",
"age" : 0.0,
"math" : NumberInt(84),
"language" : NumberInt(99),
"classes" : "一年级二班",
"Hobby" : "蓝色1"
}
{
"_id" : ObjectId("62303f0c8a0c4bd7d10ac95e"),
"name" : "张0",
"gender" : "女",
"age" : 0.0,
"math" : NumberInt(84),
"language" : NumberInt(99),
"classes" : "一年级二班",
"Hobby" : "蓝色2"
}
**/
-------------------------------------------------------------------------------------------------------------------------
$geoNear
geoNear options>}
介绍:
指定经纬度点,从mongodb中查询,最近到最远的顺序输出文档。
案例:参考这里
-------------------------------------------------------------------------------------------------------------------------
$bucket
格式:
{ $bucket: { groupBy: <expression>, boundaries: [ <lowerbound1>, <lowerbound2>, ... ], default: <literal>, output: { <output1>: { <$accumulator expression> }, <outputN>: { <$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<Test> result = mongoTemplate
.aggregate(newAggregation, "你的表名", 实体类.class);
//获取结果
List<Test> mappedResults = result.getMappedResults();
}
springBoot整合mongoDB
pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
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<Test> result = mongoTemplate.aggregate(aggregation, "你的表名", Test.class);
//获取结果
List<Test> mappedResults = result.getMappedResults();
}
---------------------------------mongoClient案例-----------------------------------------
//mongo查询语句
db.getCollection("table1").aggregate([
{$lookup:{
from:"tabl2",
let: {
pid: "$id"
},
pipeline: [
{
$match: {
$expr: {
$eq: ["$$pid", "$disId"]
}
}
},
{$match:{dataType:{$eq:NumberInt(0)}}}
],
as: "spotCheck",
}},
{$addFields:{spotCheckCount:{$size:"$spotCheck"}}},
{$group:{_id:"$CREATEUSER",spotCheckCount:{$first:"$spotCheckCount"},createUser:{$first:"$CREATEUSER"},totalCount:{$sum:1}}}
])
//java代码
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCursor;
@Autowired
private MongoClient mongoClient;
@Autowired
private MongoConverter mongoConverter;
@Test
public void test(){
//关联查询
Bson lookup = Aggregates.lookup(
"table2",
Arrays.asList(new Variable<>("disid", "$id")),
Arrays.asList(
Aggregates.match(
Filters.expr(
Document.parse("{$eq: ['$$pid', '$disId']}")
)),
Aggregates.match(
Filters.eq("dataType", 0)),
Aggregates.sort(Sorts.descending("abnormal"))
),
"spotchecks");
Bson addFields = Aggregates.addFields(
Arrays.asList(
//获取数组的长度
new Field<>("spotCheckCount", Document.parse("{$size:'$spotCheck'}")),
new Field<>("halfwayCheckCount", Document.parse("{$size:'$halfwayCheck'}"))
)
);
//分组
Bson group = Aggregates.group(
"$CREATEUSER",
Arrays.asList(
new BsonField("spotCheckCount", Document.parse("{$first:'$spotCheckCount'}")),
new BsonField("halfwayCheckCount", Document.parse("{$first:'$halfwayCheckCount'}")),
new BsonField("createUser",Document.parse("{$first:'$CREATEUSER'}")),
new BsonField("totalCount",Document.parse("{$first:'$CREATEUSER'}")),
new BsonField("createUser",Document.parse("{$sum:1}"))
));
AggregateIterable<Document> aggregateResult =
mongoClient
.getDatabase("数据库名")
.getCollection("表名")
.aggregate(
Arrays.asList(lookup, addFields, group));
MongoCursor<Document> iterator = aggregateResult.iterator();
while (iterator.hasNext()){
//封装结果
Map read = mongoConverter.read(Map.class, iterator.next());
}
}
Java操作MongoDB技巧:
mongoDB的数学运算符,数组操作符,字符串操作符等,在java中大多都可以用
<xxx.运算符名称>的方式调用。
例如:
注意引包: 都是
org.springframework.data.mongodb.core.aggregation.*包中的
java操作mongodb的客户端有两个
org.springframework.data.mongodb.core.MongoTemplate @Autowired private MongoTemplate mongoTemplate; import com.mongodb.client.MongoClient; @Autowired private MongoClient mongoClient;
以上内容全部是介绍的MongoTemplate的操作方式
mongo文档1:腾讯mongo文档(中文)
mongo文档2: mongo中文文档(内容全但是翻较差)