目录
一 : 普通操作
MongoDB的普通查询MongoTemplate与Mysql的JdbcTemplate或者说是Redis的RedisTemplate别无二致 , 使用方式完全相同;
在使用之间创建一个临时使用的test集合, 结构如下
db.getCollection("testDocuments").insert( {
_id: ObjectId("5fe9439e66730000e70058d0"),
name: "huang",
age: 21,
gender: "男"
} );
db.getCollection("testDocuments").insert( {
_id: ObjectId("5fe943bb66730000e70058d1"),
name: "lu",
age: 26,
gender: "男"
} );
db.getCollection("testDocuments").insert( {
_id: ObjectId("5fe943cf66730000e70058d2"),
name: "huang",
age: 2,
gender: "女"
} );
实例:
-
插入文档
1 . 使用mongoTemplate直接插入自定义实体类
MongoTestDTO mongoTestDTO = new MongoTestDTO();
mongoTestDTO.setName("huangxiapkuan");
mongoTestDTO.setAge("21");
mongoTestDTO.setGender("男");
mongoTemplate.insert(mongoTestDTO , "testDocuments");
2 . 使用mongoTemplate插入Mongo自带可动态扩展实体类Document.class
import org.bson.Document
// 批量插入 改为 insertMany(List<Document>) 即可
mongoTemplate.insert(new Document("name" , "zhang")
.append("age" , "33").append("gender" , "男"), "testDocuments");
3 . MongoTemplate提供了官方客户端驱动的封装,官方客户端有的方法,它都能调用 , 此外还提供了一种更统一的execute方法,
它通过注册一个回调,来实现MongoDB操作以及数据回传:
mongoTemplate.execute(mongodb -> {
mongodb.getCollection("testDocuments").insertOne(new Document("name" , "isnert3")
.append("age" , "33").append("gender" , "男"));
return "sucess";
});
4 . Mongo原生SQL如下:
db.testDocuments.insert({
name: 'huang',
age: 2,
gender: '男'
})
-
删除文档
1 . 使用mongoTemplate进行删除操作 , 需要提供Query也就是条件 , 和集合名 , 注意以下使用的 remove()更换为 findAllAndRemove() 则为批量删除
删除条件 name = ''insert3'' 的 数据
Query query = new Query();
// Criteria 可自定义创建条件
query.addCriteria(Criteria.where("name").is("insert3"));
mongoTemplate.remove(query , "testDocuments");
删除条件 _id = ''5feae0eb47801f7dfef1bf2d'' 的 数据
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("5feae0eb47801f7dfef1bf2d")));
mongoTemplate.remove(query , "testDocuments");
2 . 使用 MongoTemplate.execute 来执行回调函数 ,用来进行删除操作 , 官方客户端有的方法,它都能调用
mongoTemplate.execute( mongodb -> {
mongodb.getCollection("testDocuments").deleteOne(new Document("name","isnert3"));
return "sucess";
});
// 又或者
mongoTemplate.execute("testDocuments" ,mongodb -> {
mongodb.deleteOne(new Document("name","isnert3"));
return "sucess";
});
3 . MongoDb原生SQL删除语句如下
db.testDocuments.remove({
'name': 'insert3'
})
-
更新文档
1 . 使用MongoTemplate.upsert(Query , Update , CollectionName) 进行更新操作
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("5feafa9b47801f7dfef1bf2e")));
Update update = new Update();
update.set("name" , "new_set_values");
UpdateResult result = mongoTemplate.upsert(query, update, "testDocuments");
long count = result.getModifiedCount();
if (count > 0) {
return ApiResult.success("win!~");
}
2 . 使用MongoTemplate.execute() 回调函数进行更新操作
// 注意这里 使用的 不是 Update 而是 Updates
String execute = mongoTemplate.execute("testDocuments", mongodb -> {
UpdateResult result = mongodb.updateMany(new Document("name", "isnert3"), Updates.set("name", "upr_execute_name"));
long count = result.getModifiedCount();
if (count > 0) {
return "success";
}
return "error";
});
3 . 使用MongoDb原生SQl 进行更新操作
db.getCollection('testDocuments').updateOne({
name: 'new_set_values'
}, {
$set: {
name: 'Mongo_set_name_new'
}
})
-
查询操作
由于是测试用
1 . 使用MongoTemplate进行查询操作
普通查询
// 查询所有
List<Document> testDocuments = mongoTemplate.find(new Query(), Document.class, "testDocuments");
// 条件查询 , 根据_id查询指定值
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("5feafa9b47801f7dfef1bf2e")));
mongoTemplate.find(query, Document.class, "testDocuments");
// 也可以直接使用MongoTemplate提供的 findById()
mongoTemplate.findById("5feafa9b47801f7dfef1bf2e",Document.class , "testDocuments");
// 条件查询,查询特定name值
Query query = new Query();
query.addCriteria(Criteria.where("name").is("huang"));
List<Document> testDocuments = mongoTemplate.find(query, Document.class, "testDocuments");
// 条件查询,查询特定name值 ,或者age年龄大于30的
Query query = new Query();
Criteria criteria = new Criteria();
criteria.orOperator(Criteria.where("name").is("huang") , Criteria.where("age").gte(30));
query.addCriteria(criteria);
List<Document> testDocuments = mongoTemplate.find(query, Document.class, "testDocuments");
// 条件查询,查询特定name值,并且年龄大于20的
Query query = new Query();
Criteria criteria = new Criteria();
criteria.andOperator(Criteria.where("name").is("huang") , Criteria.where("age").gte(20));
query.addCriteria(criteria);
List<Document> testDocuments = mongoTemplate.find(query, Document.class, "testDocuments");
//条件查询 , 分页查询 skip(0) 从第0条开始 , limit(2) 查询两条
Query query = new Query();
query.skip(0);
query.limit(2);
mongoTemplate.find(query, Document.class, "testDocuments");
//条件查询 , 排序 sort 可同时针对多个字段进行排序, 不过当数据量过大时可能会出现内存不足
// 具体解决办法可参照 https://blog.csdn.net/qq_42543063/article/details/111380373
Query query = new Query();
// query.with(Sort.by("age").descending()); // 倒序
query.with(Sort.by("age").ascending()); // 正序
mongoTemplate.find(query, Document.class, "testDocuments");
2 . MongoTemplate提供的回调与正常方法别无二致, 可按照增删改的样例自行探索..........
二 : 聚合操作
MongoDB 中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。
有点类似 SQL 语句中的 count(*)。
aggregate() 方法
MongoDB中聚合的方法使用aggregate()。
语法
aggregate() 方法的基本语法格式如下所示:
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
聚合基础查询
一下是本次测是使用的数据
-
聚合查询、排序、分组、分页、Concat拼接
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.group("name")
.max("age").as("maxAge")
);
AggregationResults<Document> testDocuments =
mongoTemplate.aggregate(aggregation, "testDocuments", Document.class);
等同于Mongo原生SQL如下:
、
查询结果 , 可以发现 , name被当做了_id , 且只查询出来了两个属性
{"_id":"upr_execute_name","maxAge":33},{"_id":"huang","maxAge":21},{"_id":"lu","maxAge":26}
可以将上面的聚合操作修改为如下
// 除却max 函数外 聚合操作还提供了 avg min sum 等常用计算函数
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(Criteria.where("gender").is("男")), // 查询条件
Aggregation.project("name", "age", "gender")
.andExpression("concat('$gender', '人')").as("genderNew")
,// 可利用 andExpression() 继续操作某些特定值 加减乘如 或者拼接字符串
Aggregation.group("name")
.max("age").as("maxAge") // 取最大年龄 , 别名为 maxAge
.first("name").as("name") // 分组后取该组内第一条name
.first("age").as("age")
.first("gender").as("gender"),
Aggregation.skip(0L), // 始于第几条 mongo建议使用long类型
Aggregation.limit(2L), // 查询多少条
Aggregation.sort(Sort.Direction.DESC,
"age" , "name") // 可同时使用多字段排序 , 需注意当数据量过大时容易造成内存不足 具体解决办法 请参照 https://blog.csdn.net/qq_42543063/article/details/111380373
);
AggregationResults<Document> testDocuments =
mongoTemplate.aggregate(aggregation, "testDocuments", Document.class);
查询结果样例为:
{"_id":"huang","maxAge":21,"name":"huang","age":21,"gender":"男"},{"_id":"lu","maxAge":26,"name":"lu","age":26,"gender":"男"}
-
聚合查询链表关联查询
为了验证关联查询操作 , 此处需新建一个mongo的集合 , 旨在测试用 , 具体业务不严谨!!!
主表为 testDocuments 关联表为 testRel
// 创建条件集合
List<AggregationOperation> aggregationOptions = new ArrayList<>();
LookupOperation lookupOperation = LookupOperation.newLookup()
.from("testRel") // 指定关联表
.localField("name") // 关联表字段
.foreignField("name") // 关联表字段
.as("rel"); // 关联表别名
aggregationOptions.add(lookupOperation); // 作为条件添加至条件集合
// 为关联表创建条件
aggregationOptions.add(Aggregation.match(Criteria.where("rel").elemMatch(Criteria.where("name").ne("").ne(null))));
aggregationOptions.add(Aggregation.group("name")
.max("age").as("maxAge")
.first("name").as("name")
.first("age").as("age")
.first("gender").as("gender")
.first("rel.address").as("assress"));
// 将条件集合创建成聚合操作Aggregation
Aggregation aggregation = Aggregation.newAggregation(aggregationOptions);
AggregationResults<Document> testDocuments =
mongoTemplate.aggregate(aggregation, "testDocuments", Document.class);