springboot调用mongo

随便测试了一下,有问题请指出

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();
    }
}
posted @ 2019-10-16 16:30  复合式→展开式  阅读(1122)  评论(0)    收藏  举报