依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

注解

注解 描述 示例
@Document 对应于MongoDB中的Collection(默认类名小写) @Document(collection="user")
@Id 主键,默认生成的名称是“_id”。在MongoDB中数据的主键通常为自动生成的复杂字符串,不需要我们手动设置
@Field 对应于collection中自定义的字段,不手动添加该注解时MongoDB中的数据字段跟Entity的属性名一致 @Field("name")
@DBRef 引用其他的文档,这个文档有可能位于其他数据库中(级联关系)
@Transient 该字段不保存到 mongodb
@Indexed 声明该字段需要索引,建索引可以大大的提高查询效率。direction参数可以指定排序方向,升或降序。 @Indexed(direction = DESCENDING)
@PersistenceConstructor 用于声明构造函数,作用是把从数据库取出的数据实例化为对象。
    //声明构造函数,用于实例化查询结果数据
    @PersistenceConstructor
    public Entity(Long parameter1, String parameter2) {
        this.parameter1 = parameter1;
        this.parameter2 = parameter2;
    }


    复合索引,指的是将多个键组合到一起创建索引,这样可以加速匹配多个键的查询。
    复合索引可以支持要求匹配多个键的查询
    复合索引每一个键的顺序非常重要,这将决定该索引在查询过程中能否被使用到
    复合索引查询时先按 userid 升序 再按 score 降序{'userid:1','score':-1}。

    索引键列的排序方法影响查询在排序时候的操作,方向一致或相反的才能被匹配

    { "item": 1, "location": 1, "stock": 1 }    //索引
 
    在MongoDB中,下列查询过滤条件情形中,索引将会被使用到
            item字段
            item字段 + location字段(尽管索引被使用,但不高效)
            item字段 + location字段 + stock字段

    创建联合索引(用于类,以声明复合索引)
    @CompoundIndexes({
        //联合索引 name 索引名称 、def 索引字段、parameter1升序、parameter2降序
        @CompoundIndex(name = "compound_index", def = "{'parameter1': 1, 'parameter2': -1}")
    })

    执行语句db.Example.find({"userId":"1"}).explain();


    @DBRef关联其他集合(不添加此注释时List将会保存具体的实体值,而添加了此注释List保存的是关联集合的id和表名)
    只保存了Entity的id和表名,同时仍然没有创建Entity的collection(等同于mysql的表)。
    不会处理级联保存,你必须单独处理关联的对象
    先储存关联对象,再储存主体对象,查询主体对象可以将关联对象一并查出。
    @DBRef
    private List<Entity> parameter;

Query常用方法介绍

query(CriteriaDefinition criteriaDefinition)

    静态方法,通过注入一个CriteriaDefinition条件对象获得Query查询对象。在简单查询时使用此方法将非常的方便。
    例如:mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date())

addCriteria(CriteriaDefinition criteriaDefinition)

    添加一个CriteriaDefinition查询条件类到本次查询

skip(long skip)

    跳过文档的数量,可以与limit配合使用实现分页效果。

limit(int limit)

    查询返回的文档数量。

with(Sort sort)

    添加一个Sort排序对象

with(Pageable pageable)

    添加一个Pageable分页对象。Pageable可以注入一个Sort,所以分页和排序可以一起添加。
    例如:Pageable pageable = new PageRequest(1,3,sort);

Criteria 查询条件类

where(String key)	
    静态方法,用它可以很方便的定义查询条件
    例如:mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date()).and("parameter2").regex("es"))
语法 描述
and(String key) 与操作
gt(Object o) 大于
gte(Object o) 大于等于
in(Object... o) 包含
is(Object o) 等于
lt(Object o) 小于
lte(Object o) 小于等于
not()
regex(String re) 正则表达式
andOperator(Criteria... criteria) 创建与操作
orOperator(Criteria... criteria) 创建或操作

基本使用

public class MongoController {

    @Autowired
    private MongoTemplate mongoTemplate;

    //新增文档
    public void insert() {

        //insert方法并不提供级联类的保存,所以级联类需要先自己先保存
        EntityTest1 entityTest1_1 = new EntityTest1(1000L);
        //执行完insert后对象entityTest1将会获得保存后的id
        mongoTemplate.insert(entityTest1_1);

        //创建列表并将保存后的关联对象添加进去
        ArrayList<EntityTest1> entityTest1List = new ArrayList<EntityTest1>();
        entityTest1List.add(entityTest1_1);

        //新增主体对象
        EntityTest entityTest = new EntityTest(100L, "test", new Date(), 10, entityTest1List);
        //新增数据的主键已经存在,则会抛DuplicateKeyException异常
        mongoTemplate.insert(entityTest);
    }

    //保存文档
    //保存与新增的主要区别在于,如果主键已经存在,新增抛出异常,保存修改数据
    public void save() {

        //查询最后一条数据并更新
        Sort sort = new Sort(Sort.Direction.DESC, "parameter3");
        EntityTest entityTest = mongoTemplate.findOne(Query.query(Criteria.where("")).with(sort), EntityTest.class);
        entityTest.setParameter4(3000);
        //保存数据的主键已经存在,则会对已经存在的数据修改
        mongoTemplate.save(entityTest);
    }

    //删除文档
    public void delete() {

        //查询第一条数据并删除
        EntityTest entityTest = mongoTemplate.findOne(Query.query(Criteria.where("")), EntityTest.class);

        //remove方法不支持级联删除所以要单独删除子数据
        List<EntityTest1> entityTest1List = entityTest.getParameter5();
        for (EntityTest1 entityTest1 : entityTest1List) {
            mongoTemplate.remove(entityTest1);
        }

        //删除主数据
        mongoTemplate.remove(entityTest);
    }

    //更新文档
    public void update() {
        //将查询条件符合的全部文档更新
        Query query = new Query();
        Update update = Update.update("parameter2", "update");
        mongoTemplate.updateMulti(query, update, EntityTest.class);
    }

    //查询文档
    public void find(Model model) {
        //查询小于当前时间的数据,并按时间倒序排列
        Sort sort = new Sort(Sort.Direction.DESC, "parameter3");
        List<EntityTest> findTestList = mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date())).with(sort), EntityTest.class);

        //使用findOne查询如果结果极为多条,则返回排序在最上面的一条
        EntityTest findOneTest = mongoTemplate.findOne(Query.query(Criteria.where("parameter3").lt(new Date())).with(sort), EntityTest.class);

        //模糊查询
        List<EntityTest> findTestList1 = mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date()).and("parameter2").regex("es")), EntityTest.class);

        //分页查询(每页3行第2页)
        Pageable pageable = new PageRequest(1, 3, sort);
        List<EntityTest> findTestList2 = mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date())).with(pageable), EntityTest.class);

        //共多少条
        Long count = mongoTemplate.count(Query.query(Criteria.where("parameter3").lt(new Date())), EntityTest.class);

        //返回分页对象
        Page<EntityTest> page = new PageImpl<EntityTest>(findTestList2, pageable, count);

        //分页查询(通过起始行和数量也可以自己实现分页逻辑)
        List<EntityTest> findTestList3 = mongoTemplate.find(Query.query(Criteria.where("parameter3").lt(new Date())).with(sort).skip(3).limit(3), EntityTest.class);
    }
}