特点

  • 集合中的文档可以不定长(类比讲,表中的字段长度可以不一致,表中的列可以不一样长)

对比

mysqlmongoDB
数据库数据库
collection
文档
字段属性

注意

  • 集合只有在文档插入之后才会真正创建
  • update多个匹配只会更新1条
  • update只更新指定属性
  • replaceOne会把匹配文档用新文档整个替换
  • 官方推荐使用delete,delete与remove
  • 使用objectId获取时间是UTC时间比北京时间晚了8小时
  • mongodb中的时间都是UTC时间比北京时间晚了8小时
  • objectId中的时间精确到秒,new Date()时间精确到毫秒
  • 将$操作符当做key,当做属性名使用
  • skip(), limilt(), sort()三个放在一起执行的时候,执行顺序是先 sort(), 再skip(),最后limit()
  • $属性 表示取值

mongoDB时区

mongoDB UTC +0:00,中国时区是 UTC +8.00
mongoDB中的存储时间比时机时间少了8小时
例如:

mongo时间中国时间
2022-05-16T08:11:19Z 即 2022-05-16 08:11:192022-05-16 16:11:19
参考网址2
参考网址1

登录

# mongo 数据库 -u 用户名 -p
mongo xcrj_db -u xcrj_user -p
# mongo 数据库 --host IP或域名 --port 端口 -u 用户名 -p
mongo xcrj_db --host localhost --port 27017 -u xcrj_user -p

连接

# mongodb://用户名:密码@IP:端口/数据库
mongodb://xcrj_user:xcrj_pwd@localhost:27017/xcrj_db

权限

创建普通用户

# 进入admin数据库
mongo admin
# 使用自定义数据库
use xcrj_db
# 创建用户并赋予权限,创建xcrj_user用户并赋予dbOwner用户在xcrj_db数据库上
db.createUser({ user:'xcrj_user',pwd:'xcrj_pwd',roles:[ { role:'dbOwner', db: 'xcrj_db'}]});
# 查看xcrj_db数据库
show dbs

创建root用户

# 登录
mongo admin
# 查看当前所在数据库,默认在admin数据库
use admin
# 创建root用户,本质:为root用户赋予userAdminAnyDatabase角色作用在admin数据库上,为root用户赋予readWriteAnyDatabase角色作用在所有数据库上
db.createUser(
  {
    user: 'root',
    pwd: 'root_pwd', 
    roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
  }
)

删除用户

# 使用数据库
use xcrj_db
# 删除用户
db.dropUser('xcrj_user')

删除所有用户

# 使用数据库
use xcrj_db
# 删除当前库所有用户
db.dropAllUser()

查看所有用户

# 使用数据库
use xcrj_db
#查看这个数据库下的所有用户
show users;

授予角色

# 使用数据库
use xcrj_db
#授权语句,拥有管理用户权限的账户才能对用户进行授权
db.grantRolesToUser('xcrj_user',[{role:'dbOwner',db:'xcrj_db'}])

回收角色

# 使用数据库
use xcrj_db
#回收权限语句,拥有管理用户权限的账户才能回收用户
db.revokeRolesFromUser("xcrj_user",[{ role: "dbOwner", db: "xcrj_db" }])

内置角色

基本角色

角色名权限
root包含角色readWriteAnyDatabase、dbAdminAnyDatabase、userAdminAnyDatabase、clusterAdmin、restore和backup联合之后所有的权限。
dbOwner在当前db中执行任意操作
userAdmin用户管理,在当前db中管理user的权限
read只读数据权限
readWrite读写数据权限

备份还原

角色名权限
backup备份权限
restore还原权限

跨库角色

角色名权限
readAnyDatabase在所有数据库上都有读取数据的权限
readWriteAnyDatabase在所有数据库上都有读写数据的权限
userAdminAnyDatabase在所有数据库上都有管理user的权限
dbAdminAnyDatabase管理所有数据库的权限

集群管理角色

角色名权限
clusterAdmin管理机器的最高权限
clusterManager管理和监控集群的权限
clusterMonitor监控集群的权限
hostManager管理Server

自定义角色

todo(xcrj)

数据库

使用数据库

use xcrj_db

删除数据库

# 使用数据库
use xcrj_db
# 删除数据库
db.dropDatabase()

查看当前所在数据库

db

查看所有数据库

show dbs

集合

创建集合

# 使用数据库
use xcrj_db
# 创建集合
db.createCollection("xcrj_col")

创建集合-插入文档

# 使用数据库
use xcrj_db
# 插入文档自动创建集合
db.xcrj_col.insert({"time" : "2021-12-05"})

删除集合

# 使用数据库
use xcrj_db
# 删除集合
db.xcrj_col.drop()
# 删除集合特殊名称
db.getCollection('2').drop()

查找集合

db.getCollection('xcrj_col').find({})

查看所有集合

show collections

文档

insert-语法

  • writeConcern:是否确认写操作。默认为 1,要求确认写操作;0 是不要求确认写操作。
  • ordered:是否顺序写入。默认 1,按顺序写入;0是不按顺序写入。
db.collection.insertMany(
   [ <document 1> , <document 2>, ... ],
   {
      writeConcern: <document>,
      ordered: <boolean>
   }
)

insert

db.xcrj_col.insert({
  name: 'xcrj', 
  age: 24,
  score: 12.55,
  is_human: true,
  now_time: new Date(),
  skills: ['mongodb', 'database', 'NoSQL'],
  relationMap: {
    brother: 'tt',
	sister: 'mm'
  }
})

insert-变量

# 创建document
doc = ({
  name: 'xcrj', 
  age: 24,
  score: 12.55,
  is_human: true,
  now_time: new Date(),
  skills: ['mongodb', 'database', 'NoSQL'],
  relationMap: {
    brother: 'tt',
	sister: 'mm'
  }
})
# 插入document
db.xcrj_col.insert(doc)

inserOne

db.xcrj_col.insertOne({
  name: 'xcrj', 
  age: 24,
  score: 12.55,
  is_human: true,
  now_time: new Date(),
  skills: ['mongodb', 'database', 'NoSQL'],
  relationMap: {
    brother: 'tt',
	sister: 'mm'
  }
})

insertMany

db.xcrj_col.insertMany([
  {
    name:'jobs',
    hobby:'apple'
  },
  {
    name:'lj',
    hobby:'xiaomi'
  },
  {
    name:'xcrj',
    hobby:'code'
  }])

deleteOne

db.xcrj_col.deleteOne({name:"xcrj"})

deleteMany-条件

db.xcrj_col.deleteMany({name:"xcrj"})

deleteMany-所有

db.xcrj_col.deleteMany ({})

remove-语法

  • justOne:删除1条
  • writeConcern:抛出异常的级别
db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)

remove-条件

db.xcrj_col.remove({"name":'xcrj'})

remove-1条

db.xcrj_col.remove({"name":'xcrj'},{justOne:1})

remove-所有

db.xcrj_col.remove({})

update-语法

  • upsert:有则更新,无则插入
  • multi:更新多条。默认1条
  • writeConcern:抛出异常的级别
db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

update-1个

  • 注意:多个匹配只会更新1条
  • 注意:replaceOne会把匹配文档用新文档整个替换
  • 注意:update只更新指定属性
db.xcrj_col.update({name:'jobs'},{$set:{name:'lbs'}})

update-多个

db.xcrj_col.update({name:'jobs'},{$set:{name:'lbs'},{multi:true}})

replaceOne-替换

  • 注意:会把匹配文档用新文档整个替换
# db.xcrj_col.replaceOne(条件,需要替换的新记录)
db.xcrj_col.replaceOne(
    {name:"xcrj"},
    {name:"xcrj007",hobby:"coding"}
)

replaceOne-替换或插入

  • 注意:会把匹配文档用新文档整个替换或插入
# db.xcrj_col.replaceOne(条件,需要替换或插入的新记录,开启upsert)
db.xcrj_col.replaceOne(
    {name:"xcrj"},
    {name:"xcrj",hobby:"code"},
    {upsert:true}
)

replaceOne-排序

  • collation参考
  • locale:语言简写
  • strength:比较强度
  • collation:先比较第1个属性,再比较第2个属性,从小到大
# db.xcrj_col.replaceOne(条件,需要替换的新记录,开启collation)
db.xcrj_col.replaceOne(
    {name:"xcrj"},
    {name:"xcrj",hobby:"ANTA"},
    {collation:{locale:"en",strength:1}}
)

find-语法

  • projection:指定属性
db.collection.find(query, projection)

find-所有

db.xcrj_col.find({})

find({}).pretty()

db.xcrj_col.find({}).pretty()

find-_id

db.xcrj_col.find({"_id":ObjectId("55c70e51972a75fc8ae91ea7")})

findOne

db.xcrj_col.findOne({"_id":ObjectId("55c70e51972a75fc8ae91ea7")})

find-and

db.xcrj_col.find({name:"xcrj", hobby:"code"}).pretty()

find-or

db.xcrj_col.find({$or: [{name:"xcrj"}, {name:"xcrj007"}]}).pretty()

find-count

db.result_msgv1.find({mid:102,sendDate:{$gte:new Date(1641001743000)},sendDate:{$lte:new Date(1641166792000)}},{glideridIrid:1,sendDate:1}).count()

find-时间

MongoTemplate中也要用new Date()

db.result_msgv1.find({mid:102,sendDate:{$gte:new Date(1641001743000)},sendDate:{$lte:new Date(1641166792000)}},{glideridIrid:1,sendDate:1})

find-指定属性

# db.xcrj_col.find({条件},{projection})
db.xcrj_col.find({},{_id:0,name:1,hobby:1})

分页-limit-skip

# skip:跳过指定数量的数据,limit:获取指定数量的数据
db.xcrj_col.find({}).limit(1).skip(1)

sort排序

单属性排序

# -1,倒序查询;1,正序查询
db.col.find({}).sort({"hobby":-1})

多属性排序

# name正序,hobby逆序,name相同的情况下按照hobby逆序
db.col.find({}).sort({"name":1,"hobby":-1})

聚合排序-$sort

# select * from xcrj_col order by age;
db.xcrj_col.aggregate({"$sort":{"age":1}})

skip().limilt().sort()

  • skip(), limilt(), sort()三个放在一起执行的时候,执行顺序是先 sort(), 再skip(),最后limit()

sort与索引

  • 单索引{a:1}:sort({a:1})和sort({a:-1})都支持
  • 复合索引{a:1,b:1}:sort({a:1,b:1})和sort({b:1,a:1})都支持
  • 复合索引{a:1,b:-1}:sort({a:1,b:-1})和sort({a:-1,b:1})都支持

分组

简单分组

#类似 select * from xcrj_col group by hobby;
db.xcrj_col.aggregate(
    {"$group":{"_id":"$hobby"}}  
)

多级分组

# 类似 select * from xcrj_col group by name,hobby;
# $name表示取值,根据name属性的$name属性值分组
db.emp.aggregate(
    {"$group":{"_id":{"name":"$name","hobby":"$hobby"}}}
)

先条件查询再分组

#类似 select * from xcrj_col where name="xcrj" group by hobby;
db.emp.aggregate(
    {"$match":{"name":"xcrj"}},
    {"$group":{"_id":"$hobby"}}  
)

group-avg-分组平均

# 类似 select *,avg(age) as age_avg from xcrj_col group by hobby;
db.xcrj_col.aggregate(
    {"$group":{"_id":"$hobby",'age_avg':{"$avg":"$age"}}}
)

group-count-分组统计

# select count(*) as count_group from xcrj_col group by hobby; 
db.xcrj_col.aggregate({"$group":{"_id":"$hobby","count_group":{"$sum":1}}})

group-sum-分组求和

# select sum(age) as sum_age_group from xcrj_col group by hobby; 
db.xcrj_col.aggregate({"$group":{"_id":"$hobby","sum_age_group":{"$sum":"$age"}}})

group-max-每组最大

# select *,max(age) as max_age from xcrj_col group by hobby;
db.xcrj_col.aggregate({"$group":{"_id":"$hobby","max_age":{"$max":"$age"}}})

group-max-每组最小

# select *,min(age) as max_age from xcrj_col group by hobby;
db.xcrj_col.aggregate({"$group":{"_id":"$hobby","min_age":{"$min":"$age"}}})

group-first-每组第1个

db.xcrj_col.aggregate({"$group":{"_id":"$hobby","first_name":{"$first":"$name"}}})

group-last-每组最后1个

db.xcrj_col.aggregate({"$group":{"_id":"$hobby","last_name":{"$last":"$name"}}})

group-having

# select *,avg(age) as age_avg from xcrj_col group by age having age_avg > 20;
db.xcrj_col.aggregate(
    {"$group":{"_id":"$hobby",'age_avg':{"$avg":"$age"}}},
    {"$match":{"age_avg":{"$gt":20}}}
)

group_concat

  • $push允许重复
  • $addToSet不允许重复
# select hobby,group_concat(name) as names from xcrj_col group by hobby;
# $push允许重复
db.xcrj_col.aggregate({"$group":{"_id":"$hobby","names":{"$push":"$name"}}})
# $addToSet不允许重复
db.xcrj_col.aggregate({"$group":{"_id":"$hobby","names":{"$addToSet":"$name"}}})

聚合-aggregate

  • aggregate关键字
    举例
# select *,avg(age) as age_avg from xcrj_col group by age having age_avg > 20;
db.xcrj_col.aggregate(
    {"$group":{"_id":"$hobby",'age_avg':{"$avg":"$age"}}},
    {"$match":{"age_avg":{"$gt":20}}}
)

聚合管道

单管道

# select name,hobby from xcrj_col;
db.xcrj_col.aggregate({$project:{ _id:0,name:1,hobby: 1}});

多管道

  • 管道是linux或unix中的概念,前1个的输出作为后1个的输入
  • 管道构成:[{pipe1},{pipe2},{pipe3}]
# select count(*) as count from xcrj_col where age >20 and age <=30 group by hobby
db.xcrj_col.aggregate([
	{$match:{age:{$gt:20,$lte:30}}},
	{$group:{_id:hobby,count_sum:{$sum:1}}}
	]);

事务

介绍

  • 单文档操作具有原子性,不需要使用事务
  • 多文档操作需要使用事务
  • mongo事务本质是session,操作多个文档使用同一个session
  • session本质就是context

使用

  • 开启事务》执行语句》提交事务/回滚事务(发生错误)

索引

  • 索引创建在集合之上

查看索引

db.xcrj_col.getIndexes()

创建普通索引

#创建索引;1升序索引,-1降序索引
db.xcrj_col.createIndex({"name":1},{name:'idx_name'})

创建唯一索引

#创建索引;1升序索引,unique:1表示创建唯一索引
db.xcrj_col.createIndex({"idcard":1},{unique: 1,name:'uk_idcard'})

创建复合索引

# name升序,hobby降序
db.xcrj_col.createIndex({"name":1,"hobby":-1},{name:'idx_name_hobby'})

删除所有索引

db.xcrj_col.dropIndexes()

删除指定索引

db.xcrj_col.dropIndex("idx_name")

$操作符

比较运算

操作格式举例类似
={<key>:<value>}db.xcrj_col.find({"name":"xcrj"}).pretty()select * from xcrj_col where name = 'xcrj'
!={<key>:{$ne:<value>}}db.xcrj_col.find({"age":{$ne:20}}).pretty()select * from xcrj_col where age != 20
>{<key>:{$gt:<value>}}db.xcrj_col.find({"age":{$gt:20}}).pretty()select * from xcrj_col where age> 40
>={<key>:{$gte:<value>}}db.xcrj_col.find({"age":{$gte:20}}).pretty()select * from xcrj_col where age >= 50
<{<key>:{$lt:<value>}}db.xcrj_col.find({"age":{$lt:20}}).pretty()select * from xcrj_col where age < 20
<={<key>:{$lte:<value>}}db.xcrj_col.find({"age":{$lte:20}}).pretty()select * from xcrj_col where age <= 30

管道聚合

操作作用举例类似
$project限定字段db.xcrj_col.aggregate({$project:{ _id:0,name:1,hobby: 1}});select name,hobby from xcrj_col;
$match过滤数据db.xcrj_col.aggregate({"$match":{"name":"xcrj"}})select * from xcrj_col where name="xcrj";
$limit限制返回文档数量db.xcrj_col.find({}).limit(2)select * from xcrj_col limit 2;
$skip跳过指定数量的文档db.xcrj_col.find({}).skip(1).limit(2)select * from xcrj_col limit 1,2;
$group分组db.xcrj_col.aggregate({"$group":{"_id":"$hobby"}})select * from xcrj_col group by hobby;
$sort排序db.xcrj_col.aggregate({"$sort":{"age":1}})select * from xcrj_col order by age;
说明
  • 使用时将$操作符当做key,当做属性名使用

$type-类型查找

# 查找数据类型为string
db.col.find({"title" : {$type : 'string'}})
# 或
db.col.find({"title" : {$type : 2}})

$or和and联合使用-查找

# 查找and、or联合使用
db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()

$属性

  • $属性 表示取值

举例

# 类似 select * from xcrj_col group by name,hobby;
# $name表示取值,根据name属性的$name属性值分组
db.emp.aggregate(
    {"$group":{"_id":{"name":"$name","hobby":"$hobby"}}}
)

数据类型

objectId

  • 每个文档都在insert时都会自动添加1个_id属性
  • _id属性的默认值是ObjectId
  • objectId长度12bytes
  • objectId=时间戳+机器标识码+进程id+随机数
  • objectId中包含了时间戳,可以从objectId中获取时间
    在这里插入图片描述
    说明
  • UTC时间比北京时间时间晚了8小时。精确到秒,保证在1s之外的objectId不同
  • Machine标识:保证不同机器生成的objectId不同
  • PID:进程id。保证不同进程生成的object不同
  • INC:自增counter。保证1s以内相同Machine和PID情况下生成的objectId不同

从objectId中获取时间

# mongo命令行中
var obj=ObjectId()
obj.getTimestamp()

将objectId中的时间插入集合

# mongo命令行中
db.getCollection('xcrj_col').find({}).forEach(function(item){
    var _str = item._id.toString().substr(10, 8);
    var _date = new Date(Number(parseInt(_str, 16).toString() + '000'));
    item.createTime = _date;
    db.getCollection('xcrj_col').save(item);
})

获取object转string

# mongo命令行中
var obj=ObjectId()
obj.str

Date

  • mongodb中的时间都是UTC时间比北京时间晚了8小时

insert new Date()

db.xcrj_col.insert({time:new Date()})

insert new Date(“指定时间”)

# 精确到毫秒
db.xcrj_col.insert({time:new Date("2021-12-05T17:14:50.002Z")})

导入导出

# 导入
mongoimport -u xcrj_user -p xcrj_pwd -d xcrj_db -c result --file /data/db/result.mongo
# 导出
mongoexport -u xcrj_user -p xcrj_pwd -d xcrj_db -c result -o /data/db/result.mongo
# 导出 限制导出数量
mongoexport -u xcrj_user -p xcrj_pwd -d xcrj_db -c result --limit=1000 -o /data/db/result.mongo

作者声明

  • 文章如有问题,欢迎指正!!!
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐