- Java mongoTemplate
应用mongoTemplate表白mongo shell表达式。 - 应用spring boot集成mongo,而后间接跑test实操
蕴含,$group,$project等操作
package com.example.springboot;import lombok.Builder;import lombok.Getter;import lombok.Setter;import lombok.ToString;import org.aspectj.lang.annotation.Before;import org.assertj.core.util.Lists;import org.junit.jupiter.api.BeforeAll;import org.junit.jupiter.api.BeforeEach;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.data.annotation.Id;import org.springframework.data.domain.Sort;import org.springframework.data.mongodb.core.BulkOperations;import org.springframework.data.mongodb.core.MongoTemplate;import org.springframework.data.mongodb.core.aggregation.*;import org.springframework.data.mongodb.core.mapping.Document;import org.springframework.data.mongodb.core.query.Criteria;import org.springframework.data.mongodb.core.query.Query;import org.springframework.data.mongodb.core.query.Update;import org.springframework.data.mongodb.core.query.UpdateDefinition;import org.springframework.data.util.Pair;import org.springframework.util.StringUtils;import javax.swing.*;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.regex.Pattern;import java.util.stream.Collectors;import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregationOptions;/** * @see com.example.springboot.SpringbootApplicationTests#testProject() */@SpringBootTestclass SpringbootApplicationTests { @Autowired private MongoTemplate mongoTemplate; @Test void contextLoads() { } /** * 初始化student数据 */ @Test public void setupData(){ Student student = Student.builder() .id("1").name("张三").age(15).chinese(90).maths(95).physics(93).chemistry(100).biology(99).english(98).build(); Student student1 = Student.builder() .id("2").name("李四").age(18).chinese(80).maths(90).physics(93).chemistry(88).biology(93).english(83).build(); Student student2 = Student.builder() .id("3").name("王五").age(16).chinese(72).maths(80).physics(84).chemistry(77).biology(79).english(72).build(); Student student3 = Student.builder() .id("4").name("王小二").age(20).chinese(72).maths(80).physics(84).chemistry(77).biology(79).english(72).build(); Student student4 = Student.builder() .id("5").name("jim").age(20).chinese(72).maths(80).physics(84).chemistry(77).biology(79).english(79).build(); List<Student> students = Lists.newArrayList(student,student1, student2,student3, student4); BulkOperations bulkOperations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, Student.COLLECTION); bulkOperations.insert(students); bulkOperations.execute(); } /** * 初始化书籍数据 */ @Test public void setupBooksData(){ Book apue = Book.builder().id("1").title("apue").author("stevens").type("computer").copies(8).build(); Book mysqlInAction = Book.builder().id("2").title("mysql in action").author("lee").type("computer").copies(10).build(); Book redisInAction = Book.builder().id("3").title("redis in action").author("lee").type("computer").copies(5).build(); Book englishABC = Book.builder().id("4").title("english A B C").author("li lei").type("english").copies(15).build(); Book toefl = Book.builder().id("5").title("toefl").author("li lei").type("english").copies(10).build(); Book chinese = Book.builder().id("6").title("chinese A B C").author("zhang san").type("chinese").copies(12).build(); List<Book> students = Lists.newArrayList(apue, mysqlInAction, redisInAction, englishABC, toefl, chinese); BulkOperations bulkOperations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, Book.COLLECTION); bulkOperations.insert(students); bulkOperations.execute(); } @Test public void insertOneStudent(){ Student student3 = Student.builder() .id("7").name("jeff").age(19).chinese(73).maths(80).physics(84).chemistry(77).biology(79).english(72).build(); mongoTemplate.insert(student3); } /** * 数据中没有则保留,有这更新 */ @Test public void saveOneStudent(){ Student student3 = Student.builder() .id("7").name("jeff").age(100).chinese(73).maths(80).physics(84).chemistry(77).biology(79).english(72).build(); mongoTemplate.save(student3); } @Test public void batchSave(){ // 见数据初始化处 } /** * update 批量更新, */ @Test public void testBatchUpdate(){ List<Pair<Query, Update>> updates = new ArrayList<>(); for (int i = 0; i < 5; i ++){ Query query = new Query(); Criteria criteria = new Criteria().and("_id").is(i+ ""); query.addCriteria(criteria); Update update = Update.update("age", i); updates.add(Pair.of(query, update)); } BulkOperations bulkOperations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, "student"); bulkOperations.updateMulti(updates); bulkOperations.execute(); } /** * 将查问进去的后果对立批改。 * mongoTemplate.upsert 办法,如果不存在,则新建一条记录。存在则更新,十分有用。 */ @Test public void testUpdate(){ Query query = new Query(); Criteria criteria = new Criteria().and("age").is(18); query.addCriteria(criteria); UpdateDefinition update = Update.update("english", 99); mongoTemplate.updateMulti(query, update, "student"); } /** * find $in */ @Test public void testFindByIn(){ Query query = new Query(); Criteria criteria = new Criteria().and("age").in(18,19,20); query.addCriteria(criteria);// query.withHint("age"); // 举荐mongo应用索引 query.skip(1); query.limit(10); query.with(Sort.by(Sort.Direction.DESC, "age")); String qString = query.getQueryObject().toString(); System.out.println(qString); List<Student> students = mongoTemplate.find(query, Student.class); System.out.println(students); } /** * 正则 * db.student.find({name : /Jim/i}); 都是疏忽大小写的 * db.student.find({name : {$regex: "Jim", $options: "$i"}}); */ @Test public void testFindByRegex(){ String regexStr = "^JI";// Criteria criteria = new Criteria().and("name").regex(regexStr, "I"); // I 疏忽大小写 Pattern pattern = Pattern.compile(regexStr, Pattern.CASE_INSENSITIVE); Criteria criteria = new Criteria().and("name").regex(pattern); Query query = Query.query(criteria); List<Student> students = mongoTemplate.find(query, Student.class); System.out.println(students); } /** * group author. * "pipeline" : [{ "$match" : {}}, { "$group" : { "_id" : "$author", "copiesTotal" : { "$sum" : "$copies"}, "copiesMax" : { "$max" : "$copies"}, "avg" : { "$avg" : "$copies"}}}] */ @Test public void TestGroup() { List<AggregationOperation> operations = Lists.newArrayList(); Criteria criteria = new Criteria(); // todo 减少过滤条件 operations.add(Aggregation.match(criteria)); GroupOperation groupOperation = new GroupOperation(Fields.fields("author")). sum("copies").as("copiesTotal"). max("copies").as("copiesMax"). avg("copies").as("avg"); operations.add(groupOperation); Aggregation aggregation = Aggregation.newAggregation(operations) .withOptions(newAggregationOptions().allowDiskUse(true).build()); AggregationResults<Map> aggregationResults = mongoTemplate.aggregate(aggregation, "book", Map.class); System.out.println(aggregationResults.getMappedResults()); } /** * $group 字段为null时,去所有$match匹配的文档都为一个分组。 * $push 将字段退出某个数组,所有group的分组中的字段都退出 * $addToSet 和push相比会去重 * * "pipeline" : [{ "$match" : {}}, { "$group" : { "_id" : null, "authurs" : { "$push" : "$author"}}}, { "$project" : { "_id" : 0}}] * "pipeline" : [{ "$match" : {}}, { "$group" : { "_id" : null, "authors" : { "$push" : "$author"}, "uniqueAuthors" : { "$addToSet" : "$author"}}}, { "$project" : { "_id" : 0}}] */ @Test public void testPush(){ List<AggregationOperation> operations = Lists.newArrayList(); Criteria criteria = new Criteria(); operations.add(Aggregation.match(criteria)); GroupOperation groupOperation = Aggregation.group(). push("author").as("authors") .addToSet("author").as("uniqueAuthors"); operations.add(groupOperation); ProjectionOperation projectionOperation = Aggregation.project().andExclude("_id"); operations.add(projectionOperation); Aggregation aggregation = Aggregation.newAggregation(operations) .withOptions(newAggregationOptions().allowDiskUse(true).build()); AggregationResults<Map> aggregationResults = mongoTemplate.aggregate(aggregation, "book", Map.class); System.out.println(aggregationResults.getMappedResults()); } /** * $unwind 根据某个字段数组拆分成独自的文档。 * "pipeline" : [{ "$match" : {}}, { "$group" : { "_id" : null, "authors" : { "$push" : "$author"}, "uniqueAuthors" : { "$addToSet" : "$author"}}}, { "$project" : { "_id" : 0}}, { "$unwind" : "$authors"}] */ @Test public void testUnwind(){ List<AggregationOperation> operations = Lists.newArrayList(); Criteria criteria = new Criteria(); operations.add(Aggregation.match(criteria)); GroupOperation groupOperation = Aggregation.group(). push("author").as("authors") .addToSet("author").as("uniqueAuthors"); operations.add(groupOperation); ProjectionOperation projectionOperation = Aggregation.project().andExclude("_id"); operations.add(projectionOperation); operations.add(Aggregation.unwind("authors")); Aggregation aggregation = Aggregation.newAggregation(operations) .withOptions(newAggregationOptions().allowDiskUse(true).build()); AggregationResults<Map> aggregationResults = mongoTemplate.aggregate(aggregation, "book", Map.class); System.out.println(aggregationResults.getMappedResults()); } /** * project解决english和maths之和,并不输入id字段。 * "pipeline" : [{ "$match" : {}}, { "$project" : { "ts" : { "$add" : ["$english", "$maths"]}, "_id" : 0}}] */ @Test public void testProject(){ List<AggregationOperation> operations = Lists.newArrayList(); Criteria criteria = new Criteria(); operations.add(Aggregation.match(criteria)); ProjectionOperation projectionOperation = new ProjectionOperation(); Fields fields = Fields.fields("student"); projectionOperation.andInclude(fields); projectionOperation = Aggregation.project().and("english").plus("maths").as("ts").andExclude("_id"); operations.add(projectionOperation); Aggregation aggregation = Aggregation.newAggregation(operations) .withOptions(newAggregationOptions().allowDiskUse(true).build()); AggregationResults<Map> aggregationResults = mongoTemplate.aggregate(aggregation, "student", Map.class); System.out.println(aggregationResults.getMappedResults()); } /** * project 输入指定字段,排除其余字段 * "pipeline" : [{ "$match" : {}}, { "$project" : { "name" : 1, "english" : 1, "maths" : 1, "chinese" : 1, "_id" : 0}}] */ @Test public void testProjectField(){ List<AggregationOperation> operations = Lists.newArrayList(); Criteria criteria = new Criteria(); operations.add(Aggregation.match(criteria)); ProjectionOperation projectionOperation = new ProjectionOperation(); Fields fields = Fields.fields("name", "english", "maths", "chinese"); projectionOperation = projectionOperation.andInclude(fields).andExclude("_id"); // Aggregation.project(fields).andExclude("_id"); operations.add(projectionOperation); Aggregation aggregation = Aggregation.newAggregation(operations) .withOptions(newAggregationOptions().allowDiskUse(true).build()); AggregationResults<Map> aggregationResults = mongoTemplate.aggregate(aggregation, "student", Map.class); System.out.println(aggregationResults.getMappedResults()); } /** * 统计学生几门课的总分。 * 存在问题,如果一个学生的某个课程分数为null,或者活没有该字段,则统计的total为null. * "pipeline" : [{ "$match" : {}}, { "$project" : { "total" : { "$add" : ["$english", "$maths", "$chinese"]}}}] */ @Test public void testAggregate(){ List<AggregationOperation> operations = Lists.newArrayList(); Criteria criteria = new Criteria(); operations.add(Aggregation.match(criteria)); ProjectionOperation projectionOperation; AggregationExpression aggregationExpression = ArithmeticOperators.Add.valueOf("english") .add("maths") .add("chinese"); projectionOperation = Aggregation.project().and(aggregationExpression).as("total"); operations.add(projectionOperation); Aggregation aggregation1 = Aggregation.newAggregation(operations) .withOptions(newAggregationOptions().allowDiskUse(true).build()); AggregationResults<Map> aggregationResults1 = mongoTemplate.aggregate(aggregation1, "student", Map.class); System.out.println(aggregationResults1.getMappedResults()); } /** * 怎么多个$or一起操作。 * "pipeline" : [{ "$match" : { "name" : "张三", "$or" : [{ "maths" : { "$gte" : 90}}, { "english" : { "$gte" : 90}}, { "chinese" : { "$gte" : 90}}]}}] */ @Test public void testOrOperation(){ List<AggregationOperation> operations = Lists.newArrayList(); Criteria criteria = new Criteria(); criteria = criteria.and("name").is("张三"); Criteria criteria1 = new Criteria().and("maths").gte(90); Criteria criteria2 = new Criteria().and("english").gte(90); Criteria criteria3 = new Criteria().and("chinese").gte(90); criteria = criteria.orOperator(criteria1, criteria2, criteria3); operations.add(Aggregation.match(criteria)); Aggregation aggregation = Aggregation.newAggregation(operations).withOptions(newAggregationOptions().allowDiskUse(true).build()); AggregationResults<Student> results = mongoTemplate.aggregate(aggregation, "student", Student.class); System.out.println(results.getMappedResults()); } @Setter @Getter @ToString @Document(Student.COLLECTION) @Builder static class Student{ public static final String COLLECTION = "student"; public static final String MATHS = "maths"; public static final String CHINESE = "chinese"; public static final String ENGLISH = "english"; public static final String PHYSICS = "physics"; public static final String CHEMISTRY = "chemistry"; public static final String BIOLOGY = "biology"; @Id private String id; private String name; private int age; private int maths; private int chinese; private int english; private int physics; private int chemistry; private int biology; } @Setter @Getter @ToString @Document(Book.COLLECTION) @Builder static class Book { public static final String COLLECTION = "book"; @Id private String id; private String title; private String author; private int copies; // 库存数 private String type; }}