MongoDB的入门

NorthnightX / 2023-08-16 / 原文

简介

MongoDB是一个由C++语言编写的、基于分布式文件存储的、开源、高性能、无模式的文档型数据库,在高负载的情况下,添加更多的节点,可以保证服务器性能,MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。它是NoSQL数据库产品中的一种,是最像关系型数据库的非关系型数据库。

以下是常见的使用场景:

  1. 直播数据、打赏数据、粉丝数据
    • 存储位置:数据库、Mongodb
    • 特征:永久性存储与临时存储相结合,修改频度极高
  2. 游戏装备数据、游戏道具数据
    • 存储位置:数据库、Mongodb
    • 特征:永久性存储与临时存储相结合、修改频度较高

数据库操作

创建数据库

use test

查看有权限查看到所有数据库命令

show dbs

删除当前的数据库

db.dropDatabase()

创建集合

db.createCollection("test")

删除集合

db.test.drop()

文档操作

新增文档

如果没有所用的集合“test”,会隐式的创建集合

db.test.insertOne({"name" : "user", "age" : "17", "gender" : "man"})
db.test.insertMany([
	{"name" : "user", "age" : "17", "gender" : "man"},
	{"name" : "user1", "age" : "18", "gender" : "man"},
	{"name" : "user2", "age" : "19", "gender" : "man"},
])

查询文档

// 查询所有文档
db.test.find()
// 条件查询
db.test.find({"name" : "user"})
// 只查询第一条
db.test.findOne({"name" : "user"})
// 只查询部分字段,会显示id
db.test.find({"name" : "user"}, {name : 1})
// 只查询部分字段,不显示id
db.test.find({"name" : "user"}, {name : 1, _id : 0})

更新

// 修改符合条件的第一条数据
db.test.updateOne({"name" : "user1"}, {$set : {"age" : "14"}})
// 修改符合条件的全部数据
db.test.updateMany({"name" : "user"}, {$set : {"age" : "15"}})
db.test.insertOne({"name" : "user3", "age" : "18", "gender" : "man", "count" : 31})
// 字段自增,MongoDB从MongoDB 3.2 版本引入了整数类型
db.test.updateOne({"name" : "user3"}, {$inc : {count : 1}})

删除

// 删库跑路
db.test.deleteMany({})
// 删除单个
db.test.deleteOne({"name" : "user1"})
// 删除多个
db.test.deleteMany({"name" : "user"})

分页查询

// 查询数量
db.test.count()
// 限制查询条数
db.test.find().limit(1)
db.test.find().skip(1).limit(1)
// 排序: 1是升序,-1是降序
db.test.find().sort({count : -1})
// 正则表达式模糊查询
db.test.find({name : /2/})
// 比较查询 gt大于,lt小于,大于等于gte,小于等于lte,不等于ne
db.test.find({count : {$gt : 1}})
db.test.find({count : {$lt : 1}})
// 包含查询
db.test.find({count : {$in : [null, 32]}})
// 多条件连接查询
db.test.find({$and : [{name : "user3"}, {count : 32}]})

索引

// 查看索引
db.test.getIndexes()
// 创建索引
db.test.createIndex({name : 1})
// 创建联合索引
db.test.createIndex({name : 1, age : -1})
// 删除索引
db.test.dropIndex("name_1_age_-1")
// 删除所有索引
db.test.dropIndexes("*")

Java操作MongoDB

引入依赖

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

配置文件

data:
  mongodb:
    uri: mongodb://username:password@8.140.17.235:27017/db

声明映射的实体类

@Document:标识该实体类是一个MongoDB文档的映射,@MongoId:声明文档的主键字段

@Data
@Document("blogdto")
public class BlogDTO {
	@TableId(type = IdType.AUTO)
	@MongoId
	private Integer id;
}

查询

找到映射类: 根据 BlogDTO.class 找到对应的映射类,即BlogDTO。
获取文档注解信息: 在映射类上,框架会查找 @Document 注解,并从中获取文档的名称。

查询所有

@Test
void testFind(){
    Query query = new Query();
    List<BlogDTO> blogDTOList = mongoTemplate.find(query, BlogDTO.class);
    blogDTOList.forEach(System.out::println);
}

条件查询

@Test
void testConditionalQuery(){
    Query query = new Query();
    //构造查询条件
    query.addCriteria(Criteria.where("_id").is(22));
    BlogDTO blogDTO = mongoTemplate.findOne(query, BlogDTO.class);
    System.out.println(blogDTO);
}

分页查询

@Test
void page(){
    Query query = new Query();
    //从第10条开始,查3条
    query.skip(10).limit(3);
    //只查询title和clickCount两个字段
    query.fields().include("title").include("clickCount");
    //根据clickCount排序
    query.with(Sort.by(Sort.Direction.ASC, "clickCount"));
    List<BlogDTO> blogDTOList = mongoTemplate.find(query, BlogDTO.class);
    System.out.println(blogDTOList.size());
    blogDTOList.forEach(System.out::println);
}

复合查询

@Test
void testQuery(){
    Query query = new Query();
    // in查询
    Criteria criteriaIn = Criteria.where("_id").in(Arrays.asList(1, 2, 3));
    // and查询
    Criteria criteriaTitle = Criteria.where("title").is("数据库");
    Criteria criteriaStatus = Criteria.where("status").is(1);
    Criteria criteriaAnd = new Criteria().andOperator(criteriaTitle, criteriaStatus);
    // or查询
    Criteria criteriaOr = new Criteria().orOperator(criteriaTitle, criteriaStatus);
    // 逻辑运算符查询
    Criteria criteria = Criteria.where("clickCount").gt(10).lte(0);
    // 正则表达式查询
    String regex = "^好*";
    Criteria criteriaRegex = Criteria.where("title").regex(regex);
    BlogDTO blogDTO = mongoTemplate.findOne(query, BlogDTO.class);
    System.out.println(blogDTO);
}

新增

@Test
void insertOne(){
    BlogDTO blogDTO = new BlogDTO();
    // 如果数据库中存在和当前存储对象id相同的,会报错
    mongoTemplate.insert(blogDTO);
    // 如果数据库中存在和当前存储对象id相同的,会更新
    mongoTemplate.save(blogDTO);
}

@Test
void insertMany(){
    List<BlogDTO> list = new ArrayList<>();
    mongoTemplate.insertAll(list);
}

删除

@Test
void deleteTest(){
    Query query = new Query();
    query.addCriteria(Criteria.where("_id").is(22));
    // 删除符合条件的所有文档
    mongoTemplate.remove(query, BlogDTO.class);
    // 删除符合条件的所有文档并返回删除的文档
    mongoTemplate.findAllAndRemove(query, BlogDTO.class);
    // 删除符合条件的第一条文档并返回删除的文档
    mongoTemplate.findAndRemove(query, BlogDTO.class);
}

修改

@Test
void updateTest(){
    Query query = new Query();
    query.addCriteria(Criteria.where("_id").is(22));
    Update update = new Update();
    // 字段自增
    update.inc("clickCount", 1);
    // 更新的字段
    update.set("title", "test");
    mongoTemplate.updateFirst(query, update, BlogDTO.class);
    mongoTemplate.updateMulti(query, update, BlogDTO.class);
}