MongoDB

1、SQL到MongoDB的映射图

SQLMongoDB
数据库(database)数据库(database)
表(table)集合(collection)
行row文档(document)
列(column)字段(field)
索引(index)索引(index)
主键(primary key)_id(字段)
视图 (view)视图 (view)
表连接(table joins)聚合操作 ($lookup)

在这里插入图片描述

2、适合使用MongoDB的场景

  1. 应用不需要复杂/长事务及 join 支持
  2. 新应用,需求会变,数据模型无法确定,想快速迭代开发
  3. 应用需要2000-3000以上的读写QPS (更高也可以)
  4. 应用需要TB甚至 PB 级别数据存储
  5. 应用发展迅速,需要能快速水平扩展
  6. 应用要求存储的数据不丢失
  7. 应用需要99.999%高可用
  8. 应用需要大量的地理位置查询、文本查询

3、Linux安装

https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.26.tgz

命令1
进入bin目录,输入./mongo --help查看帮助信息
在这里插入图片描述
命令2

  1. 指定data和log路径
    在这里插入图片描述

  2. 启动mongoDB

bin/mongod --port=27017 --dbpath=/app/mongodb-linux-x86_64-rhel70-4.4.26/data --logpath=/app/mongodb-linux-x86_64-rhel70-4.4.26/log/mongodb.log --bind_ip=0.0.0.0 --fork

  1. 进入bin目录打开mongoDB命令控制台
    在这里插入图片描述

4、基础命令

  1. 查看所有数据库
show dbs

在这里插入图片描述
2. 创建(切换)db
在这里插入图片描述

  1. 在控制台关闭mongoDB服务
db.shutdownServer()

在这里插入图片描述
在这里插入图片描述
菜鸟教程更多
https://www.runoob.com/mongodb/mongodb-tutorial.html

5、配置文件启动mongoDB

5.1、编辑编制文件


systemLog:
  destination: file
  path: /app/mongodb-linux-x86_64-rhel70-4.4.26/log/mongodb.log #指定日志输入文件夹(绝对路径)
  logAppend: true
storage:
  dbPath: /app/mongodb-linux-x86_64-rhel70-4.4.26/data #指定数据输入文件夹(绝对路径)
  engine: wiredTiger #存储引擎
  journal:
    enabled: true  #是否启动journal日志
net:
  bindIp: 0.0.0.0
  port: 27017
processManagement:
  fork: true

5.2、启动MongoDB

mongod -f /app/mongodb-linux-x86_64-rhel70-4.4.26/mongo.conf #启动配置文件绝对路径

在这里插入图片描述
进入bin目录输入./mongo打开命令控制台
在这里插入图片描述

5.3、关闭MongoDB

mongod -f /app/mongodb-linux-x86_64-rhel70-4.4.26/mongo.conf --shutdown ##配置文件绝对路径

在这里插入图片描述

6、Mongo shell

在这里插入图片描述
在这里插入图片描述
数据库操作

#查看所有数据库
show dbs
#use 切换数据库(创建)
use demodb
#删除当前数据库
db.dropDatabase()

集合操作

#查看所有集合
show collections
#创建集合
db.createCollection("studenttable")
#删除集合
db.studenttable.drop()

在这里插入图片描述

7、安全认证

7.1、创建管理员账号

#设置管理员用户密码需要在admin库
use admin
#创建管理员
db.createUser({user:"zmc",pwd:"123456",roles:["root"]})
#查看所有用户信息
show users
#删除用户
db.dropUser("zmc")
#验证用户
db.auth("zmc","123456")

在这里插入图片描述

权限名描述
read允许用户读取指定数据库
readWrite允许用户读写指定数据库
dbAdmin允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
dbowner允许用户在指定数据库中执行任意操作,增、删、改、查等
userAdmin允许用户向system.users集合写入,可以在指定数据库里创建、删除和管理用户
clusterAdmin只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限
readAnyDatabase只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnvDatabase只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限
root只在admin数据库中可用。超级账号,超级权限

7.2、授权方式启动

  1. 加上--auth启动mongodb
mongod -f /app/mongodb-linux-x86_64-rhel70-4.4.26/mongo.conf --auth

在这里插入图片描述

  1. 使用有权限的账号密码认证
mongo -uzmc -p123456 --authenticationDatabase=admin

在这里插入图片描述

8、MongoDB文档操作

8.1、新增文档

新增单个文档

  • db.collection.insertOne()支持writeConcern
db.collection.insertOne(
   <document>,
   {
      writeConcern: <document>
   }
)

writeConcern 决定一个写操作落到多少个节点上才算成功。writeConcern 的取值包括
0:发起写操作,不关心是否成功;
1:集群最大数据节点数: 写操作需要被复制到指定节点数才算成功
majority: 写操作需要被复制到大多数节点上才算成功。

db.student_info.insertOne({name:"小明",age:41,sex:"男"})

在这里插入图片描述

  • insert: 若插入的数据主键已经存在,则会抛 DuplicateKeyException 异常,提示主键重复,不保存当前数据.
db.student_info.insert({name:"李四",age:20,sex:"男"})

在这里插入图片描述

新增多个文档

  • insertMany()新增多个
db.collection.insertMany(
   [ <document 1> , <document 2>, ... ],
   {
      writeConcern: <document>,
      ordered: <boolean>
   }
)

writeConcern: 写入策略,默认为 1,即要求确认写操作,0 是不要求
ordered:指定是否按顺序写入,默认 true,按顺序写入

insert和save也可以实现批量插入

db.student_info.insertMany([{name:"王五",age:21,sex:"女"},{name:"赵六",age:23,sex:"女"}])

在这里插入图片描述

  • save:如果 id 主键存在则更新数据,如果不存在就插入数据。

8.2、练习测试

  • 创建js文件
let tags=["nosql","MongoDB","document","developer","popular"];
let types =["technology","sociality","travel","novel","literature"];
var books=[];
for(let i=0;i<60;i++){
	let tagIndx=Math.floor(Math.random()*tags.length);
	let tyIndx=Math.floor(Math.random()*types.length);
	let favCount=Math.floor(Math.random()*120);
	let book={
		title:"book_"+(i+1),
		type:types[tyIndx],
		tag:tags[tagIndx],
		favCount:favCount,
		author:"zmc_"+(i+1)
	};
	books.push(book);
}
db.books.insertMany(books);
  • 载入数据库
load("/app/mongodb-linux-x86_64-rhel70-4.4.26/js/book.js") #js文件的绝对路径

在这里插入图片描述

在这里插入图片描述

8.3、查询文档

find

db.collection.find(query,projection)

query :可选,使用查询操作符指定查询条件相当于sql中的where

projection:可选,使用投影操作符指定返回的键(相当于返回sql表中指定的字段)。查询时返回文档中所有键值,只需省略该参数即可(默认省略)。投影时,id为1的时候,其他字段必须是1 ; id是0的时候,其他字段可以是0;如果没有_id字段约束,多个其他字段必须同为0或同为1。

例题

  • 查询title是book_2的数据
db.books.find({title:"book_2"})

在这里插入图片描述

  • 查询title是book_1并且author是author的数据
db.books.find({title:"book_1",author:"zmc_1"})

在这里插入图片描述

  • 查询type是"travel",tag是"document",但是只想返回title,type,tag三个字段
db.books.find({type:"travel",tag:"document"},{title:1,type:1,tag:1})

在这里插入图片描述

findOne

同find一样,但是findOne只返回第一条数据

db.collection.findOne(query,projection)
db.books.findOne({type:"travel",tag:"document"},{title:1,type:1,tag:1})

在这里插入图片描述

sql与mongodb查询条件对照表

SQLMongoDB
filed=1{field:1}
filed<>1{field:{$ne:1}}
filed>1{field:{$gt:1}}
filed>=1{field:{$gte:1}}
filed<1{field:{$lt:1}}
filed<=1{field:{$lte:1}}
filed1=1 AND filed2=3{field1:1, filed2:3}或{$and:[{field1:1},{field2:3}]}
filed1=1 OR filed2=3{$or:[{field1:1},{field2:3}]}
filed IS NULL{field:{$exists:false}}
filed IN (1,2,3){field:{$in:[1,2,3]}}
filed NOT IN (1,2,3){field:{$nin:[1,2,3]}}

例:

  • 1
#tag!=nosql 并且 type!=technology
db.books.find({tag:{$ne:"nosql"},type:{$ne:"technology"}})

在这里插入图片描述

  • 2
#favCount>99
db.books.find({favCount:{$gt:99}})

在这里插入图片描述

  • 3
#type=sociality 或者 tag=MongoDB
db.books.find({$or:[{type:"sociality"},{tag:"MongoDB"}]})

在这里插入图片描述

  • 4
#查询不存在author字段的数据,如果author=null或author=""则查不到
db.books.find({author:{$exists:false}})

{}

  • 5
#tag IN ('nosql','popular','MongoDB',)
db.books.find({tag:{$in:["nosql","popular","MongoDB"]}})

在这里插入图片描述

排序

#查询type=sociality或者tagMongoDB,再根据type正序排序favCount倒序排序
db.books.find({$or:[{type:"sociality"},{tag:"MongoDB"}]}).sort({type:1,favCount:-1})

在这里插入图片描述

分页

#查询favCount>=60,再跳过前三条数据,限制为5条数据
db.books.find({favCount:{$gte:60}}).skip(3).limit(5)

在这里插入图片描述

正则匹配(模糊)查询

#type包含ve,相当于sql的type like '%ve%' 
db.books.find({type:{$regex:"ve"}})

在这里插入图片描述
也可以这样写

db.books.find({type:/ve/})

在这里插入图片描述

8.4、更新文档

db.collection.update(query,update,options)
  • query:描述更新的查询条件;相当于sql的where条件
  • update:描述更新的动作及新的内容;相当于sql的set
  • options:描述更新的选项
    • upsert:可选, 如果不存在update的记录,是否插入新的记录。默认false,不插入
    • multi:可选,是否更新多条记录。默认false,只更新找到的第一条记录
    • writeConcern :可选,决定一个写操作落到多少个节点上才算成功。

更新操作符

操作符格式描述
$set{$set:{field:value}}指定一个键并更新值,若键不存在则创建
$unset{$unset:{field:1}}删除一个键
$inc{$inc : {field : value } }对数值类型进行增减
$rename{$rename :{old_field_name :new_field_name } }修改字段名称
$push{ $push : {field : value } }将数值追加到数组中,若数组不存在则会进行初始化
$pushAll{$pushAll : {field : value_array}}追加多个值到一个数组字段内
$pull{$pull : {field : _value } }从数组中删除指定的元素
$addToSet{$addToSet : {field : value } }添加元素到数组中,具有排重功能
$pop{$pop : {field : 1 }}删除数组的第一个或最后一个元素

更新单个文档update

#把type=travel的数据,favCount减去100
db.books.update({type:"travel"},{$inc:{favCount:-100}})

在这里插入图片描述
在这里插入图片描述

更新单个文档updateOne

db.books.updateOne({type:"travel"},{$set:{createDate:"2133-12-23T11:48:22.913Z"}})

在这里插入图片描述

替换单个文档replaceOne

db.books.replaceOne({type:"travel"},{"title" : "book_116", "type" : "travel", "tag" : "developer", "favCount" : 81, "author" : "zmc_6", "createDate" : ISODate("2023-12-23T11:48:22.913Z")})

在这里插入图片描述

不使用操作符实现替换文档

不可实现替换多个文档

#彻底替换整个文档
db.books.update({type:"zmc"},{oneField:12222})

在这里插入图片描述

更新多个文档update

需要配合使用multi,设置为true

#更新多行数据,并添加createDate字段(如果没有该字段,则新增该字段)
db.books.update({type:"travel"},{$set:{createDate:new Date()}},{multi:true})

在这里插入图片描述

更新多个文档updateMany

db.books.updateMany({type:"travel"},{$set:{createDate:new Date()}})

在这里插入图片描述

不存在则插入upsert

db.books.update({type:"zmc"},{$set:{createDate:"2133-12-23T11:48:22.913Z",tag:[1,2,3]}},{upsert:true})

在这里插入图片描述

查询和修改单个文档findAndModify

findAndModify只能更新单个文档

  • 先查询旧值再更新文档
#先查询title=book_1的数据,再把该条数据的athor修改为zhangmengchao
db.books.findAndModify({query:{title:"book_1"},update:{$set:{author:"zhangmengchao"}}})

在这里插入图片描述

  • 先更新文档再查询修改后的内容
    加上参数new,设置为true
db.books.findAndModify({query:{title:"book_2"},update:{$set:{author:"zhangmengchao2"}},new:true})

在这里插入图片描述
与findAndModify语义相近的命令如下:
findOneAndUpdate:更新单个文档并返回史新前(或更新后)的文档。. findOneAndReplace:替换单个文档并返回替换前(或替换后的文档。

8.5、删除文档

删除多个文档remove

#删除type是sociality和novel并且favCount>=18的数据
db.books.remove({type:{$in:["sociality","novel"]},favCount:{$gte:18}})

满足条件的有17个全删了
在这里插入图片描述

删除单个文档remove

#justOne为true,代表只删除一个文档
db.books.remove({type:"travel"},{justOne:true})

在这里插入图片描述

删除所有文档remove

db.books.remove({})

删除单个文档deleteOne

#删除type=novel或者tag为MongoDB,并且favCount>100的一条数据
db.books.deleteOne({$or:[{type:"novel"},{tag:{$in:["MongoDB"]}}],favCount:{$gt:100}})

在这里插入图片描述

删除多个文档deleteMany

#删除type=novel或者tag为MongoDB,并且favCount>100的多条数据
db.books.deleteMany({$or:[{type:"novel"},{tag:{$in:["MongoDB"]}}],favCount:{$gt:100}})

在这里插入图片描述
删除所有文档

db.books.deleteMany({})

查询和删除单个文档findOneAndDelete

  • 删除文档后并返回删的文档
#删除author=zhangmengchao的文档
db.books.findOneAndDelete({"author" : "zhangmengchao"})

在这里插入图片描述

  • 先排序再删除文档
#查询出满足tag=popular的所有文档,再倒序排序。删除第一个文档
db.books.findOneAndDelete({"tag" : "popular"},{sort:{favCount:-1}})

在这里插入图片描述
remove、deleteOne等命令只能按默认顺序删除,利用这个特性, findOneAndDelete可以实现队列的先进先出。

9、MongoDB Compass (GUI)

https://downloads.mongodb.com/compass/mongodb-compass-1.41.0-win32-x64.exe
在Linux环境部署MongoDB需要开放MongoDB的端口
在这里插入图片描述
进入后的画面
在这里插入图片描述

10、整合SpringBoot

10.1、环境配置

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-mongodb -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
spring:
  data:
    mongodb:
      database: zmcdb
      host: 192.168.0.104
      port: 27017
      username: zmc
      password: '123456'   #注意密码加单引号
      authentication-database: admin
      #或者
#     uri: mongodb://zmc:123456@192.168.0.104:27017/zmcdb?authSource=admin

10.2、注入MongoTemplate

@Autowired
private MongoTemplate mongoTemplate;

10.3、 集合操作

    /**
     * 判断集合(表)是否存在,删除集合(表),创建集合(表)
     */
    @Test
    public void createCollections() {
        final String COLLECTION_NAME = "student_info";
        boolean exists = mongoTemplate.collectionExists(COLLECTION_NAME);
        if (exists) {
            mongoTemplate.dropCollection(COLLECTION_NAME);
        }
        mongoTemplate.createCollection(COLLECTION_NAME);
    }

10.4、相关注解

@Document

  • 修饰范围:用在类上
  • 作用:用来映射这个类的一个对象为mongo中一条文栏数据。
  • 属性:( value 、collection )用来指定操作的集合名称

@MongoId

  • 修饰范围:用在成员变量、方法上
  • 作用:用来将成员变量的值映射为文档的id的值

@Field

  • 修饰范围:用在成员变量、方法上
  • 作用:用来将成员变量及其值映射为文档中一个key:value对。
  • 属性:( name , value )用来指定在文档中key的名称,默认为成员变量名

@Transient

  • 修饰范围:用在成员变量、方法上
  • 作用:用来指定此成员变量不参与文档的序列化
@Document("student_info")
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class StudentInfoDTO {
    @MongoId
    private Integer id;
    @Field("stuName")//自定义文档的字段名
    private String name;
    @Field
    private Integer age;
    @Field
    private Character sex;
    @Field
    private Date birthday;

}

10.5、新增文档

新增单个文档insert

id不能重复,如果重复就会抛出异常

@Test
    public void insertSingle() {
        StudentInfoDTO dto=new StudentInfoDTO(1,"张三",23,'男',new Date());
        StudentInfoDTO insert = mongoTemplate.insert(dto);
    }

在这里插入图片描述
相同id再次新增就会报错
在这里插入图片描述

新增多个文档insert

    @Test
    public void insertMore() {
        List<StudentInfoDTO> listDto=new ArrayList<>(3);
        StudentInfoDTO dto1=new StudentInfoDTO(2,"小明",2,'男',new Date());
        StudentInfoDTO dto2=new StudentInfoDTO(3,"小黑",21,'女',new Date());
        StudentInfoDTO dto3=new StudentInfoDTO(4,"小白",20,'男',new Date());
        listDto.add(dto1);
        listDto.add(dto2);
        listDto.add(dto3);
        Collection<StudentInfoDTO> insert = mongoTemplate.insert(listDto, StudentInfoDTO.class);
    }

在这里插入图片描述

新增单个文档save

若id存在,则修改该文档

@Test
    public void saveSingle() {
        StudentInfoDTO dto=new StudentInfoDTO(1,"老六",213,'男',new Date());
        StudentInfoDTO save = mongoTemplate.save(dto);
    }

在这里插入图片描述

10.6、查询文档

Criteria是标准查询的接口,可以引用静态的Criteria.where的把多个条件组合在起,就可以轻松地将多个方法标准和查询连接起来,方便我们操作查询语句。

Criteria、MongoDB、SQL对比

CriteriaMongoDBSQL
Criteria and (String key)$andwhere field1=1 and field2=2
Criteria andOperator(Criteria… criteria)$andwhere field1=1 and field2=2
Criteria orOperator (Criteria. … criteria)$orwhere field1=1 or field2=2
Criteria gt (Object o)$gtwhere field>1
Criteria gte (Object o)$gtewhere field>=1
Criteria in (Object… o)$inwhere field in (1,2,3)
Criteria is (Object o)$iswhere field =1
Criteria It(Object o)$ltwhere field<1
Criteria Ite (Object o)$ltewhere field<=1
Criteria nin (Object… o)$ninwhere field not in (1,2,3)

查询所有文档findAll

    @Test
    public void criteriaFind() {
        //查询age>20 and stuName in ('老六','小黑')
        Query query = new Query(Criteria.where("age").gt(20).and("stuName").in("老六", "小黑"));
        List<StudentInfoDTO> dtoList = mongoTemplate.find(query, StudentInfoDTO.class);
        dtoList.forEach(System.out::println);
    }

在这里插入图片描述

根据id查询文档findById

    @Test
    public void findById() {
        StudentInfoDTO byId = mongoTemplate.findById(1, StudentInfoDTO.class);
        System.out.println(byId);
    }

在这里插入图片描述

查询单个文档findOne

    @Test
    public void findOne() {
        StudentInfoDTO one = mongoTemplate.findOne(new Query(), StudentInfoDTO.class);
        System.out.println(one);
    }

在这里插入图片描述

查询所有满足条件的文档

> and in
    @Test
    public void criteriaFind() {
        //查询age>20
        Query query = new Query(Criteria.where("age").gt(20));
        List<StudentInfoDTO> dtoList = mongoTemplate.find(query, StudentInfoDTO.class);
        dtoList.forEach(System.out::println);
    }

在这里插入图片描述

> or and =
    @Test
    public void criteriaFind2() {
        //查询age>30 or stuName = '小白' and sex='男'
        Criteria criteria = new Criteria().orOperator(
                Criteria.where("age").gt(30),
                Criteria.where("stuName").is("小白")
        ).andOperator(
                Criteria.where("sex").is("男")
        );
        Query query = new Query(criteria);
        List<StudentInfoDTO> studentInfoDTOS = mongoTemplate.find(query, StudentInfoDTO.class);
        studentInfoDTOS.forEach(System.out::println);
    }

在这里插入图片描述

like
    @Test
    public void criteriaFind3() {
        //查询stuName like '%小%'
        Criteria criteria = Criteria.where("stuName").regex("小");
        Query query = new Query(criteria);
        List<StudentInfoDTO> studentInfoDTOS = mongoTemplate.find(query, StudentInfoDTO.class);
        studentInfoDTOS.forEach(System.out::println);
    }

在这里插入图片描述

order by 排序
    @Test
    public void criteriaFind4() {
        //查询sex='男' order by age desc
        Criteria criteria = new Criteria();
        criteria.andOperator(Criteria.where("sex").is("男"));
        Query query = new Query(criteria);
        query.with(Sort.by(Sort.Order.desc("age")));
        List<StudentInfoDTO> studentInfoDTOS = mongoTemplate.find(query, StudentInfoDTO.class);
        studentInfoDTOS.forEach(System.out::println);
    }

在这里插入图片描述

skip limit分页
    @Test
    public void criteriaFind5() {
        //where birthday<=当前时间 limit 1,3
        Criteria criteria = new Criteria();
        criteria.andOperator(Criteria.where("birthday").lte(new Date()));
        Query query = new Query(criteria);
        query.skip(1).limit(3);
        List<StudentInfoDTO> studentInfoDTOS = mongoTemplate.find(query, StudentInfoDTO.class);
        studentInfoDTOS.forEach(System.out::println);
    }

在这里插入图片描述

查询单个满足条件的文档

    @Test
    public void criteriaFindOne() {
        //查询age>20 and stuName not in ('老六')
        Query query = new Query(Criteria.where("age").gte(20).and("stuName").nin("老六"));
        StudentInfoDTO one = mongoTemplate.findOne(query, StudentInfoDTO.class);
        System.out.println(one);
    }

在这里插入图片描述

JSON串查询

在这里插入图片描述

json查询不能分页和排序

    @Test
    public void criteriaFind6() {
        //where age>=20 and stuName like '%小%'
        String json = "{age:{$gte:20},stuName:{$regex:\"小\"}})";
        Query query = new BasicQuery(json);
        query.with(Sort.by(Sort.Order.asc("age")));
        List<StudentInfoDTO> studentInfoDTOS = mongoTemplate.find(query, StudentInfoDTO.class);
        studentInfoDTOS.forEach(System.out::println);
    }

在这里插入图片描述

10.7、更新文档

更新第一条记录updateFirst

更新前的数据
在这里插入图片描述
更新后的数据
在这里插入图片描述

    @Test
    public void updateFirst() {
        //update table set age+10 where age > 100 or stuName in ('小明','大明')
        Criteria criteria = new Criteria();
        criteria.orOperator(Criteria.where("age").gt(100),Criteria.where("stuName").in("小明", "大明"));
        Query query = new Query(criteria);
        Update update = new Update();
        update.inc("age",10);
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, StudentInfoDTO.class);
        System.out.println(updateResult);
    }

在这里插入图片描述

更新所有满足条件的记录updateMulti

更新前的数据
在这里插入图片描述
更新后的数据
在这里插入图片描述

    @Test
    public void updateMulti() {
        //update table set age=18 where sex='女'
        Query query = new Query(Criteria.where("sex").is("女"));
        Update update = new Update();
        update.set("age", 18);
        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, StudentInfoDTO.class);
        System.out.println(updateResult);
    }

在这里插入图片描述

没有符合更新条件的则新增upsert

更新前的数据
在这里插入图片描述
更新后的数据
在这里插入图片描述

    @Test
    public void upsert(){
        //update table set stuName="zmc",age=500,sex='男',salary=999999 where id=666
        Query query = new Query(Criteria.where("id").is(666));
        Update update = new Update();
        update.set("stuName","zmc")
                .set("age",500)
                .set("salary",999999);
        UpdateResult upsert = mongoTemplate.upsert(query, update, StudentInfoDTO.class);
        System.out.println(upsert);
    }

在这里插入图片描述

10.8、删除文档remove

删除前的数据
在这里插入图片描述
删除后的数据
在这里插入图片描述

    @Test
    public void remove() {
        //delete from table where salary>100 or stuName='中白'
        Criteria criteria = new Criteria();
        criteria.orOperator(Criteria.where("salary").gt(100),Criteria.where("stuName").is("中白"));
        Query query = new Query(criteria);
        DeleteResult remove = mongoTemplate.remove(query, StudentInfoDTO.class);
        System.out.println(remove);
    }

在这里插入图片描述

11、聚合操作

如统计,求平均值,求和等。
聚合操作分为:单—作用聚合、聚合管道、MapReduce

  • 单一作用聚合:提供了对常见聚合过程的简单访问,操作都从单个集合聚合文档。
  • 聚合管道:类似Stream流
  • MapReduce操作具有两个阶段:处理每个文档并向每个输入文档发射一个或多个对象的map阶段,以及reduce组合map操作的输出阶段。

11.1、单一聚合操作

count

#统计type=novel或者tag=MongoDB的数量
db.books.count({$or:[{"type" : "novel"},{"tag" : "MongoDB"}]})

在这里插入图片描述

estimatedDocumentCount

该命令会忽略查询条件

db.books.estimatedDocumentCount({$or:[{"type" : "novel"},{"tag" : "MongoDB"}]})

在这里插入图片描述

distinct

db.books.distinct("type",{$or:[{"type" : "novel"},{"tag" : "MongoDB"}]})

在这里插入图片描述

11.2、聚合管道类似Stream流

语法

pipeline = [$stage1,$stage2,$stage3...]
db.collection.aggregate(pipeline ,{options})
  • pipelines一组数据聚合阶段。除 o u t 、 out、 outMerge和$geonear阶段之外,每个阶段都可以在管道中出现多次
  • options可选,聚合操作的其他参数。包含:查询计划、是否使用临时文件、游标、最大操作时间、读写策略、强制索引等等
    在这里插入图片描述
    在这里插入图片描述

常用操作

在这里插入图片描述
官方文档
https://www.mongodb.com/docs/manual/reference/operator/aggregation-pipeline/

数据准备

let tags=["nosql","MongoDB","document","developer","popular"];
let types =["technology","sociality","travel","novel","literature"];
var books=[];
for(let i=0;i<60;i++){
	let tagIndx=Math.floor(Math.random()*tags.length);
	let tagIndx2=Math.floor(Math.random()*tags.length);
	let tyIndx=Math.floor(Math.random()*types.length);
	let favCount=Math.floor(Math.random()*120);
	let username="zmc"+Math.floor(Math.random()*10);
	let age=20+Math.floor(Math.random()*16);
	let book={
		title:"book_"+(i+1),
		type:types[tyIndx],
		tag:[tags[tagIndx],tags[tagIndx2]],
		favCount:favCount,
		author:{name:username,age:age}
	};
	books.push(book);
}
// console.log(books)
db.books2.insertMany(books);
#载入数据
load("/app/mongodb-linux-x86_64-rhel70-4.4.26/js/books2.js")

在这里插入图片描述
查看载入的数据

#pretty是格式化json数据
db.books2.find().pretty()

在这里插入图片描述

$project 设置别名,控制需要展示的字段

  • 设置别名
#把title改为bookName
db.books2.aggregate([{$project:{bookName:"$title"}}])

在这里插入图片描述

  • 控制需要展示的字段
#把title改为bookName,不展示id,展示type,technology,tag
db.books2.aggregate([{$project:{bookName:"$title",_id:0,type:1,technology:1,tag:1}}])

在这里插入图片描述

  • 从嵌套文档中控制需要展示的字段
db.books2.aggregate([{$project:{"author.name":1}}])
或
db.books2.aggregate([{$project:{author:{name:1}}}])

在这里插入图片描述

$match筛选文档

m a t c h 可以使用除了地理空间之外的所有常规查询操作符。实际应用中尽可能将 match可以使用除了地理空间之外的所有常规查询操作符。实际应用中尽可能将 match可以使用除了地理空间之外的所有常规查询操作符。实际应用中尽可能将match放在管道的前面位置。这样有两个好处:一是可以快速将不需要的文档过滤掉,以减少管道的工作量;二是如再投射和分组之前执行$match,查询可以使用索引.
筛选管道操作和其他管道操作配合时候时,尽量放到开始阶段,这样可以减少后续管道操作符要操作的文档数,提升效率

#author.name=zmc  只展示name
db.books2.aggregate([{$match:{"author.name":"zmc3"}},{$project:{author:{name:1}}}])
#author.name=zmc  只展示name
db.books2.aggregate([{$project:{author:{name:1}}},{$match:{"author.name":"zmc3"}}])
#type=novel
db.books2.aggregate([{$match:{type:"novel"}}])
#type like '%no%' and favCount>=60
db.books2.aggregate([{$match:{type:/no/,favCount:{$gte:60}}}])


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

$count

# select count(id) from table where type like '%no%' and favCount>=60
db.books2.aggregate([{$match:{type:/no/,favCount:{$gte:60}}},{$count:"id"}])

在这里插入图片描述

$group

g r o u p 阶段的内存限制为 100 M 。默认情况下,如果 s t a g e 迢过此限制, group阶段的内存限制为100M。默认情况下,如果stage迢过此限制, group阶段的内存限制为100M。默认情况下,如果stage迢过此限制,group将产生错误。但是,要允许处理大型数据集,请将allowDiskUse选项设置为true以启用$group操作以写入临时文件。

名称描述sql
$avg计算平均值
$first返回每组第一个文档,如果有排序,按照排序,如果没有按照默认的存储的顺序的第一个文档。limit 0,1
$last返回每组最后一个文档,如果有排序,按照排序,如果没有按照默认的存储的顺序的最后个文档。
$max根据分组,获取集合中所有文档对应值得最大值
$push将指定的表达式的值添加到一个数组中。
$addToset将表达式的值添加到一个集合中(无重复值,无序)。
$sum计算总和
$stdDevPop返回输入值的总体标准偏差
$stdDevSamp返回输入值的样本标准偏差
  • book的数量,收藏总数和平均值
#select sum(1) 数据总数, sum(favCount) favCount结果累加, avg(favCount) favCount平均 from table
 db.books2.aggregate([{$group:{_id:null,数据总数:{$sum:1},favCount结果累加:{$sum:"$favCount"},favCount平均:{$avg:"$favCount"}}}])

在这里插入图片描述

  • 统计每个作者的book收藏总数
#select author.name, sum(favCount) favCount总数 from table group by  author.name
db.books2.aggregate([{$group:{_id:"$author.name",favCount总数:{$sum:"$favCount"}}}])

在这里插入图片描述

  • 计算每种类型受欢迎的平均值,以及每种类型书的总数
#select type, avg(favCount) favCountAvg,sum(1) total from table group by type
db.books.aggregate([{$group:{_id:"$type",favCountAvg:{$avg:"$favCount"},total:{$sum:1}}}])

在这里插入图片描述

  • 计算每个作者对每种类型书的平均喜爱度
#select author.name authName,type typeBook , avg(favCount) favCountAvg from table group by author.name,type
db.books2.aggregate([{$group:{_id:{authName:"$author.name",typeBook:"$type"},favCountAvg:{$avg:"$favCount"}}}])

在这里插入图片描述

  • 每个作者的书记集合
db.books2.aggregate([{$group:{_id:{authorName:"$author.name"},types:{$addToSet:"$type"}}}])

在这里插入图片描述

TODO

  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值