MongoDB基础-集成Spring Boot

聚合操作

什么是Mongodb聚合框架?

MongoDB聚合框架(Aggregation Framewordk) 是一个计算框架,他可以作用在一个或多个集合中,对集合中的数据进行一系列运算。将这些数据转化为期望的形式。

从效果而言, 聚合框架相当于SQL查询中 Group by left join

原理

管道(Pipeline) 与 步骤(Stage)

整个聚合运算工程称之为管道, 它是由多个步骤组成
每个管道:
1:接收一系列文档(原始数据)
2:每一个步骤对这些文档进行一系列运算
3:结果文档输出给下一个步骤

基本语法

pipeline = [$stage1, $stage2, .... $stageN]

db.集合.aggregate(
     pipeline,
     {
           options
     }
)

eg:
db.user.aggregate(
      [
           {
                $group:{
                       _id:"$name",
                       namecount:{$sum:1}
                 }
            }
        ]
);

常见的步骤

$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
m a t c h :用于过滤数据,只输出符合条件的文档。 match:用于过滤数据,只输出符合条件的文档。 match:用于过滤数据,只输出符合条件的文档。match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$geoNear:输出接近某一地理位置的有序文档。

文档设计

范式

设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。 ————百度百科

反范式

打破第三范式

符合第三范式设计

employee表:

字段注释
id主键
name员工姓名
dept_id部门id

dept表:

字段注释
id主键
name部门名

需求:查询员工信息同时查询员工所在的部门信息

select e.*, d.* from employee e left join dept d on e.dept = d.id

打破第三范式

employee表:

字段注释
id主键
name员工姓名
dept_id部门id
dept_name部门名

dept表:

字段注释
id主键
name部门名

需求:查询员工信息同时查询员工所在的部门信息

select * from employee

为了提高查询效率,一般会给表加一些冗余字段,这种操作称之为打破第三范式。这种方式一般用于当查询(DQL)远远大于增删改(DML)操作。

MongoDB不建议使用 left join ,推荐使用冗余字段,打破第三范式。

使用数组方式替换一对多关系

employee表结构:

employee{
    id
    name
}

dept表结构:

dept{
	id
	name
	employees:[{},{}]
}

对象:

//employee
class Employee{
	id
	name
}

//dept
class Dept{
	id
	name
	List<Employee> es
}

集成SpringBoot

导入依赖

Spring Data MongoDb

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.3.RELEASE</version>
</parent>

<properties>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>    
    
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

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

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

配置连接参数

# application.properties
# 配置数据库连接
#格式: mongodb://账号:密码@ip:端口/数据库?认证数据库
#spring.data.mongodb.uri=mongodb://root:admin@localhost/mongodemo?authSource=admin
spring.data.mongodb.uri=mongodb://localhost/mongodemo

# 配置MongoTemplate的执行日志
logging.level.org.springframework.data.mongodb.core=debug

domain

@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
@ToString
@Document("users") //设置文档所在的集合
public class User {
    //文档的id使用ObjectId类型来封装,并且贴上@Id注解,
    // 自动映射为_id 自动封装ObjectId
    @Id
    private String id;
    private String name;
    private Integer age;
    private List<String> hobby = new ArrayList<>();
}

MongoRepository

/**
 * 自定义一个接口继承MongoRepository,
 * 泛型1:domain类型
 * 泛型2:文档主键类型
 * 贴上@Repository注解,底层会创建出动态代理对象,交给Spring管理
 */
@Repository
public interface UserMongoRepository extends MongoRepository<User, ObjectId> {
    // 使用Spring Data命名规范做高级查询
    List<User> findByName(String name);
}

Spring Data方法命名规范

关键字例子JPQL
AndfindByNameAndAge(String name, Integer age)where name = ? and age = ?
OrfindByNameOrAge(String name, Integer age)where name = ? or age = ?
IsfindByName(String name)where name = ?
BetweenfindByAgeBetween(Integer min, Integer max)where age between ? and ?
LessThanfindByAgeLessThan(Integer age)where age < ?
LessThanEqualfindByAgeLessThanEqual(Integer age)where age <= ?
GreaterThanfindByAgeGreaterThan(Integer age)where age > ?
GreaterThanEqualfindByAgeGreaterThanEqual(Integer age)where age >= ?
After等同于GreaterThan
Before等同于LessThan
IsNullfindByNameIsNull()where name is null
IsNotNullfindByNameIsNotNull()where name is not null
LikefindByNameLike(String name)where name like ?
NotLikefindByNameNotLike(String name)where name not like ?
StartingWithfindByNameStartingWith(String name)where name like ‘?%’
EndingWithfindByNameEndingWith(String name)where name like ‘%?’
ContainingfindByNameContaining(String name)where name like ‘%?%’
OrderByXx[desc]findByIdOrderByXx[Desc] (Long id)where id = ? order by Xx [desc]
NotfindByNameNot(String name)where name != ?
InfindByIdIn(List<Long> ids)where id in ( … )
NotInfindByIdNotIn(List<Long> ids)where id not in ( … )
TruefindByXxTrue()where Xx = true
FalsefindByXxFalse()where Xx = false
IgnoreCasefindByNameIgnoreCase(String name)where name = ? (忽略大小写)

实例代码

@Autowired
private UserMongoRepository repository;

// 插入/更新一个文档
@Test
public void testSaveOrUpdate() throws Exception {
    User user = new User(null, 5L, "bunny", 20);
    // 主键为null则新增,不为null则更新
    repository.save(user);
}

// 删除一个文档
@Test
public void testDelete() throws Exception {
    repository.deleteById(new ObjectId("xxx"));
}

// 查询一个文档
@Test
public void testGet() throws Exception {
    Optional<User> optional = repository.findById(new ObjectId("xxx"));
    optional.ifPresent(System.err::println);
}

// 查询所有文档
@Test
public void testList() throws Exception {
    // 查询所有文档
    List<User> list = repository.findAll();
    list.forEach(System.err::println);
}

MongoTemplate

该对象有SpringBoot完成了自动配置,存入Spring容器中,我们直接注入就可以使用了,依靠该对象能完成任何的MongoDB操作,一般和MongoRepository分工合作,多数用于复杂的高级查询以及底层操作

//注入MongoTemplate
@Autowired
private MongoTemplate template;

条件限定

Query对象用于封装查询条件,配合Criteria一起使用,来完成各种条件的描述

//一个Criteria对象可以理解为是一个限定条件
Criteria.where(String key).is(Object val); //设置一个等值条件
Criteria.orOperator(Criteria ...); //设置一组或的逻辑条件

//模糊查询(了解)
Criteria.where(String key).regex(String regex); //使用正则表达式匹配查询

注意:Criteria对象可以由其静态方法和构造器获取
Criteria封装了所有对条件的描述,常见的有以下方法
lt / lte / gt / gte / ne / ...

最后通过Query对象的addCriteria把条件封装到Query对象中

Query对象.addCriteria(Criteria criteria); //添加查询条件
Query对象.skip(start).limit(pageSize); //分页查询

API方法

//根据条件查询集合中的文档
List<T> mongoTemplate.find(Query query, Class<T> type, String collectionName);

实例代码

@Autowired
private MongoTemplate mongoTemplate

// 分页查询文档,显示第2页,每页显示3个,按照id升序排列
@Test
public void testQuery1() throws Exception {
    // 创建查询对象
    Query query = new Query();
    // 设置分页信息
    query.skip(3).limit(3);
    // 设置排序规则
    query.with(new Sort(Sort.Direction.ASC,"id"));

    List<User> list = mongoTemplate.find(query, User.class, "users");
    list.forEach(System.err::println);
}

// 查询所有name为bunny的文档
@Test
public void testQuery2() throws Exception {
    // 构建限制条件 {"name": "bunny"}
    Criteria criteria = Criteria.where("name").is("bunny");
    // 创建查询对象
    Query query = new Query();
    // 添加限制条件
    query.addCriteria(criteria);

    List<User> list = mongoTemplate.find(query, User.class, "users");
    list.forEach(System.err::println);
}

// 查询所有name为bunny或者age<30的文档
@Test
public void testQuery3() throws Exception {
    // 构建限制条件 { "$or": [{"name": "bunny"}, {"age": {"$lt": 30}}] }
    Criteria criteria = new Criteria().orOperator(
        Criteria.where("name").is("bunny"),
        Criteria.where("age").lt(30)
    );
    // 创建查询对象
    Query query = new Query();
    // 添加限制条件
    query.addCriteria(criteria);

    List<User> list = mongoTemplate.find(query, User.class, "users");
    list.forEach(System.err::println);
}

// 查询所有name含有wang并且30<=age<=32的文档
@Test
public void testQuery4() throws Exception {
    // 构建限制条件 { "$and" : [{"name": {"$regex": ".*wang.*"} }, {"age": {"$gte": 30, "$lte": 32 } }] }
    Criteria criteria = new Criteria().andOperator(
        Criteria.where("name").regex(".*wang.*"),
        Criteria.where("age").gte(30).lte(32)
    );
    // 创建查询对象
    Query query = new Query();
    // 添加限制条件
    query.addCriteria(criteria);

    List<User> list = mongoTemplate.find(query, User.class, "users");
    list.forEach(System.err::println);
}

去除 _class属性

在配置类里加@Bean

//mongodb 去除_class属性
    @Bean
    public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context, BeanFactory beanFactory) {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
        try {   mappingConverter.setCustomConversions(beanFactory.getBean(CustomConversions.class));
        } catch (NoSuchBeanDefinitionException ignore) {
        }
        // Don't save _class to mongo
        mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return mappingConverter;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: spring-boot-starter-data-mongodb是一个Spring Boot的starter,用于快速集成MongoDB数据库。它提供了MongoDB的自动配置和一些常用的操作方法,使得开发者可以更加方便地使用MongoDB进行数据存储和查询。同时,它还支持多数据源配置和集成Spring Data MongoDB等功能。 ### 回答2: Spring Boot Starter Data MongoDB是一个为Spring Boot应用提供MongoDB支持的工具包。它简化了MongoDB数据库集成,并提供了一组预定义的库,以便于开发人员快速启动MongoDB应用程序。 它提供了丰富的功能,包括CRUD操作,数据检索和管理,以及事务管理等。该工具包还提供了许多便捷的功能,如自动配置,自动映射和可插拔的错误处理机制。这些功能极大地简化了MongoDB开发的过程,帮助开发人员更快、更简单地构建高效的MongoDB应用程序。 Spring Boot Starter Data MongoDBalso统一了MongoDB数据存储和检索的方式,提供了易于使用的API,让开发人员可以快速地操作MongoDB。此外,该工具包还提供了一些高级功能,如分页查询、属性筛选和排序,使得数据检索过程更容易管理和调整。 总之,Spring Boot Starter Data MongoDB 是一个非常强大的工具包,能够帮助开发人员在Spring Boot应用中轻松集成MongoDB,并提供丰富的功能、易用的API和高效的处理机制,大大简化了MongoDB开发过程,提高了开发效率。 ### 回答3: spring-boot-starter-data-mongodb是一个基于Spring BootMongoDB开发包。MongoDB是一种常见的NoSQL数据库,它具有数据存储和查询速度快、高可扩展性、能够存储大量数据等优点。此外,MongoDB还具有面向文档的数据模型,可以轻松存储和查询复杂的嵌套数据结构。 Spring Boot为开发人员提供了一种简单的方法来快速开发基于MongoDB的应用程序。spring-boot-starter-data-mongodb提供了MongoDB数据库的自动配置和集成,无需手动编写大量的配置代码,使开发人员可以更加专注于业务逻辑的实现。 该开发包还提供了Spring Data MongoDB,这是一个强大的工具集,可以帮助开发人员轻松地进行MongoDB数据库操作。Spring Data MongoDB的核心功能包括索引支持、数据校验、CRUD操作、分页查询、异步查询和聚合查询等。 除此之外,spring-boot-starter-data-mongodb还提供了一些其他的好处,例如自动创建MongoDB数据源、自动配置MongoDB驱动程序等,这些功能使得开发人员可以更加便捷地使用MongoDB数据库。 总之,spring-boot-starter-data-mongodb使得基于MongoDB的开发变得更加简单和高效,使开发人员可以更加专注于业务实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小云很优秀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值