随便测试了一下,有问题请指出
pom.xml中添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.2</version> </dependency>
application.yml中添加连接信息
spring: data: mongodb: uri: mongodb://xxx:27017/school
测试类
@SpringBootTest @RunWith(SpringRunner.class) public class MongoDBTest { @Autowired private MongoTemplate mongoTemplate; /*@Autowired private MongoRepository mongoRepository;*/ @Autowired private GridFsTemplate gridFsTemplate; .... }
添加
通过三种形式来添加数据到mongo
@Test public void add() { // 1. 这种插入的数据的id 就直接是mongodb中的_id Student student = new Student(1, "鲁班7号", "1", 80D, Arrays.asList("玩", "虚坤", "天书世界", "贪玩蓝月")); mongoTemplate.insert(student); // 2. 使用类似map的写法,这种插入的id,是mongodb中的一个字段,会另外自动生成_id BasicDBObject obj = new BasicDBObject(); obj.put("id", 2); obj.put("name", "cxk"); obj.put("score", 95); obj.put("clazz", "2"); String[] hobby = {"唱", "跳", "篮球", "rap"}; obj.put("hobby", hobby); mongoTemplate.insert(obj, "student"); // 3. 使用json数据 会自动另外生成_id BasicDBObject parse = BasicDBObject.parse("{\n" + " \"id\": 3,\n" + " \"clazz\": \"2\",\n" + " \"score\": 90,\n" + " \"name\": \"渣渣辉\",\n" + " \"hobby\":[\"贪\",\"玩\",\"蓝\", \"月\"]\n" + "}"); mongoTemplate.insert(parse, "student"); }
student.java
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @ToString @Builder public class Student { // 与mongodb中的_id对应 private Integer id; private String name; /** * 班级 */ private String clazz; private Double score; private List<String> hobby; }
删除
@Test public void delete() { // 根据id删除 // DeleteResult id = mongoTemplate.remove(Query.query(Criteria.where("_id").is(1)), "student"); Query query = new Query(); mongoTemplate.remove(query, "student"); }
文档操作更新
/** * 文档操作 */ @Test public void update() { // 只修改第一个条记录 mongoTemplate.updateFirst(Query.query(Criteria.where("id").gt(2)), Update.update("name", "鸡太美"), "student"); // 修改匹配到的所有数据 mongoTemplate.updateMulti(Query.query(Criteria.where("id").gt(2)), Update.update("name", "鸡太美"), "student"); // 向文档中添加数据 有则跟新 没有则添加 Update update = new Update(); update.addToSet("desc", "练习时长两年半的练习生"); mongoTemplate.upsert(Query.query(Criteria.where("id").gte(2)), update, "student"); // 删除文档中的数据 Update delUpdate = new Update(); delUpdate.unset("desc"); mongoTemplate.updateMulti(Query.query(Criteria.where("id").gt(2)), delUpdate, "student"); }
简单聚合操作 count, distinct
/** * 简单聚合操作 count, distinct */ @Test public void runCommongd() { /************* count *********************/ // student集合中的总人数 select count(1) from student Document document = mongoTemplate.executeCommand("{count: 'student'}"); mongoTemplate.getCollection("student").countDocuments(); System.out.println(document); // 班级为2的人数 注意字符串要有引号 js中单引号和双引号没啥区别 select count(1) from student where clazz = '2' Document document1 = mongoTemplate.executeCommand("{count: 'student', query:{clazz: {$eq:'2'}}}"); System.out.println(document1); /************* distinct **************/ // 去掉重复的班级 select distinct clazz from student Document document2 = mongoTemplate.executeCommand("{distinct: 'student', key: 'clazz'}"); mongoTemplate.getCollection("person").distinct("clazz", Document.class); System.out.println(document2); }
普通查询
/** * 查询 */ @Test public void findTest() { // 这个id默认是mognodb中的_id Student student = mongoTemplate.findById(1, Student.class, "student"); System.out.println(student); Document doc = mongoTemplate.findById("5da57cb7f150ea3be420daf8", Document.class, "student"); //Document{{_id=5da57cb7f150ea3be420daf8, id=2, name=cxk, hobby=[唱, 跳, rap]}} System.out.println(doc); // Criteria用来构建条件 Query 用来封装所有条件 Query query = new Query(Criteria.where("_id").is("5da57cb7f150ea3be420daf9")); Document one = mongoTemplate.findOne(query, Document.class, "student"); System.out.println(one); // 正则表达式查询 (查询名字中有数字的数据) 如果不需要后面的Pattern.CASE_INSENSITIVE,直接写正则字符串就行 //Criteria regCriteria = Criteria.where("name").regex(Pattern.compile(".*\\d+.*", Pattern.CASE_INSENSITIVE)); Criteria regCriteria = Criteria.where("name").regex(".*\\d+.*"); Query regQuery = new Query(regCriteria); List<Student> student1 = mongoTemplate.find(regQuery, Student.class, "student"); System.out.println(student1); // 查询文档中的部分记录 BasicDBObject dbObject = new BasicDBObject(); // 添加查询条件 等于的那种 //dbObject.put("id", 2); // 指定返回的字段 BasicDBObject fieldsObject = new BasicDBObject(); fieldsObject.put("id", true); fieldsObject.put("name", true); fieldsObject.put("_id", false); Query basicQuery = new BasicQuery(dbObject.toJson(), fieldsObject.toJson()); // 添加查询条件 更灵活 query.addCriteria(Criteria.where("id").gt(2)); List<Document> docs = mongoTemplate.find(basicQuery, Document.class, "student"); System.out.println(docs); }
分组
group
/** * group分组 */ @Test public void group() { // 查找80分以上的人的平均得分 GroupBy groupBy = GroupBy.key("clazz") .initialDocument("{total:0, count:0}") // curr表示当前doc文档,result表示上一次处理之后的{total:0, count:0}对象 .reduceFunction("function(curr, result) {result.total += curr.score; result.count++}") // 类似于having,比having更强大,js语法去操作最后的结果 .finalizeFunction("function(result) {result.avg = Math.round(result.total/result.count);}"); Criteria criteria = Criteria.where("score").gte(80); GroupByResults<Document> brs = mongoTemplate.group(criteria, "student", groupBy, Document.class); for (Document document : brs) { System.out.println(document); } }
Aggregate
/** * aggregate聚合查询 */ @Test public void aggregateTest() { //封装查询条件 // 按班级clazz分组查询得分80以上的总分数 List<AggregationOperation> operations = new ArrayList<>(); // where operations.add(Aggregation.match(Criteria.where("score").gte(80))); // group by [这个求sum] operations.add(Aggregation.group("clazz").sum("score").as("totleScore")); // 这个求count //operations.add(Aggregation.group("clazz").count().as("totleScore")); // having //operations.add(Aggregation.match(Criteria.where("totleScore").gt(80))); Aggregation aggregation = Aggregation.newAggregation(operations); //查询、并获取结果 AggregationResults<Document> results = mongoTemplate.aggregate(aggregation, "student", Document.class); Document map = results.getRawResults(); System.out.println(map); }
mapReduce
@Test public void mapReduce() { Query query = new Query(); // emit中 key:指定分组的字段;values:要聚合的字段(数组) String mapFunction = "function() {emit(this.clazz, this.score);}"; // key:分组字段,values:根据key分组之后的值放在一个数组中,这个values就是这个数组 String reduceFunction = "function(key, values) {return Array.sum(values);}"; // 可以对结果做一些处理 MapReduceOptions mapReduceOptions = new MapReduceOptions(); // mapReduceOptions.outputCollection("aaaa"); //生成的结果表(在mongo服务器上可以看到) // mapReduceOptions.limit(2); MapReduceResults<Document> results = mongoTemplate.mapReduce(query, "student", mapFunction, reduceFunction, mapReduceOptions, Document.class); Iterator<Document> it = results.iterator(); for (;it.hasNext();) { System.out.println(it.next()); } // 查询每个人的兴趣爱好个数 Query query1 = new Query(); String mapFunction1 = "function() {emit(this.name, this.hobby);}"; String reduceFunction1 = "function(key, values) {" + "reduceVal = {name: key, hobbys: values};" + "return reduceVal;" + "}"; String func_finalize = "function(name, hobbys) {return hobbys.length}"; MapReduceOptions mapReduceOptions1 = new MapReduceOptions(); mapReduceOptions1.finalizeFunction(func_finalize); MapReduceResults<Document> results1 = mongoTemplate.mapReduce(query1, "student", mapFunction1, reduceFunction1, mapReduceOptions1, Document.class); for (Iterator<Document> it1 = results1.iterator(); it1.hasNext();) { System.out.println(it1.next()); } }
group和mapReduce的区别在于group不能跨片查询,如果是分片集群的话 使用mapReduce
查看mongo拓展的js的Array方法:
> for (var key in Array) { print(key) } contains unique shuffle tojson fetchRefs sum avg stdDev
分页查询
/** * 分页查询 */ @Test public void pageQuery() { Query query = new Query(); query.skip(1); query.limit(2); List<Document> student = mongoTemplate.find(query, Document.class, "student"); System.out.println(student); }
上传上传
/** * 文件上传 */ @Test public void uploadGridFs() throws Exception { File file = new File("E:\\1.xml"); FileInputStream fin = new FileInputStream(file); Document doc = new Document(); doc.put("filename", file.getName()); doc.put("uploadDate", new Date()); doc.put("author", "joe"); gridFsTemplate.store(fin, file.getName(), "xml", doc); }
文件下载
/** * 文件下载 */ @Test public void downLoadGridFs() throws Exception { Query query = new Query(); // query.addCriteria(Criteria.where("filename").is("1.xml")); query.addCriteria(Criteria.where("metadata.author").is("joe")); // 1.从fs.files中查询文件的相关信息 GridFSFile gfsFile = gridFsTemplate.findOne(query); // 2.从fs.chunks中获取文件(通过1中查询的files_id) GridFsResource resource = gridFsTemplate.getResource(gfsFile); InputStream in = resource.getInputStream(); FileOutputStream fout = new FileOutputStream(new File("E:\\1bak.xml")); try { byte[] buf = new byte[1024]; for (int len;(len = in.read(buf, 0, 1024)) != -1;) { fout.write(buf, 0, len); } fout.flush(); } catch (Exception e) { e.printStackTrace(); } }