MongoDB 学习笔记

作者: Guang777 | 来源:发表于2020-02-09 17:42 被阅读0次

MongoDB, MySQL和Redis的区别和使用场景

  • MySQL是关系型数据库,支持事件
  • MongoDB和Redis是非关系型数据库,不支持事件
  • 如何快速选择
    • 希望速度快的时候,使用MongoDB或者Redis
    • 数据量过大的时候,可以将频繁使用的数据存入Redis,其他的存入MongoDB
    • MongoDB不用提前建表建数据库,使用方便,字段数量不确定的时候使用MongoDB
    • 后续需要用到数据之间的关系,可以考虑MySQL

数据库常用操作

查询所有的数据库
show dbs

切换到某个数据库
use databaseName
Notice:

  • 当该数据库存在时,会切换到该数据库
  • 当数据库不存在时,会自动创建该数据库,并切换到该数据库

查看当前所处的数据库
db

集合常用操作

创建一个新的集合
db.createCollection(name,{capped,autoIndexId,size,max,...})

查询数据
db.collection.find({cretiria}):
返回所有满足过滤条件的文档

db.collection.findOne({cretiria}):
返回满足过滤条件的第一个文档

pretty():
将输出文档进行格式化

索引文档嵌套字段

对于文档:

{
   "address": {
      "city": "Los Angeles",
      "state": "California",
      "pincode": "123"
   },
   "tags": [
      "music",
      "cricket",
      "blogs"
   ],
   "name": "Tom Benzamin"
}

假设我们需要通过city,state,pincode字段来检索文档
db.users.find({'address.city':'Los Angeles'})

逻辑运算符

and :{key1:value1,key2:value2}
or :{$or:[{key1:value1},{key2:value2}]}
and ,or: {key1:value1,$or:[{key2:value2},{key3:value3}]}

范围运算符

$in: 等于数组内某个值,{age:{$in:[18,20]}}
$nin:不等于数组内任何一个值,{age:{$nin:[18,20]}}

投影

db.collection.find({},{field1:value,field2:value}):

  • 0:表示不显示
  • 1:表示显示
    Notice:
  • _id字段默认显示;
  • 括号内除_id字段,包括项(1)和排除项(0)不能同时使用

MongoDB 的更新操作

  • 以下语句会将 name 为 xiaowang的整个文档替换为 {'name':'xiaozhao'}
    db.collection.updateOne({'name':'xiaowang'},{'name':'xiaozhao'})
    db.collection.replaceOne({'name':'xiaowang'},{'name':'xiaozhao'})

  • 以下语句会将 name 为 xiaowang 的这个文档中的 name 字段更新为 xiaozhao
    db.collection.updateOne({'name':'xiaowang'},{$set:{'name':'xiaozhao'}})

  • 如果希望所有满足条件的数据都得到更新,可以使用
    db.collection.updateMany({'name':'xiaowang'},{$set:{'name':'xiaozhao'}})

  • 如果将参数 upsert设置为 true,那么当没有找到满足条件的文档时,插入的文档将作为新文档插入
    db.collection.updateOne({'name':'xiaowang'},{'name':'xiaozhao'},{'upsert':true})

MongoDB 删除操作

  • 删除满足条件的第一条数据
    db.collection.deleteOne({criterion})

  • 删除满足条件的所有数据
    db.collection.deleteMany({critetion})

统计个数

方法count()用于统计结果集合中文档的数量
db.collectionName.find({criteria}).count()

Notice:在新版本4.0中建议使用countDocuments(criteria,limit,skip,...)代替,上面的语句等价于:
db.collectionName.countDocuments({criteria})

相当于:

db.collection.aggregate([
   {$match:<query>},
   {$group:{_id:null,n:{$sum:1}}},
])

消除重复

distinct()返回文档特定字段的不同值
db.collectionName.distinct('去重字段',{条件})
db.stu.distinct(hometown,{age:{$gt:18}})

skip(), limit(), sort() 三个函数在一天语句中的时候,执行的顺序是 sort(), skip(), 最后是limit().
sort({field1:num1, field2:num2}): 1表示升序排列,-1表示降序排列

建立索引

MongoDB使用createIndex()函数来创建索引,3.0版本之前使用db.collection.ensureIndex() 函数创建索引。

  • 默认情况下,索引字段是可以有重复的

  • 如果想要创建唯一值索引,可以使用:

    • db.collection.createIndex({field:1},{unique:true})
  • 创建联合索引(对多个字段同时创建索引)

    • db.collection.createIndex({field1:1,field2:-1})
  • 查看集合内文档的所有索引

    • db.collection.getIndexes()
  • 删除索引:

    • db.collection.dropIndexes() ## 删除所有索引
    • db.collection.dropIndex(index_name) ## 删除指定索引

数据库的备份和恢复

数据库备份语句:
mongodump -h dbhost -d dbname -o dbdirectory

  • dbhost:服务器地址,
  • dbname:要备份的数据库
  • dbdirectory:存放备份数据库的路径

Notice:如果要备份本地数据库,可直接使用:
mongodump -o dbdirectory ## 会把所有的数据库文档进行备份
mongodump -d databaseName -o dbdirectory ## 会把指定的数据库进行备份

数据库恢复语句:
mongorestore -h dbhost -d dbname --dir directory

  • dbhost:服务器地址,
  • dbname:用于存放数据的数据库名称
  • directory:存放备份数据库集合的路径

Notice:如果要恢复到本地数据库,可直接使用:
mongorestore -d dbname --dir directory
Notice:这里的directory指的是集合所在的路径,是备份数据库时所指定的路径dbdirectory的下一级文件夹

数据聚合操作

聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。

常用的管道:

  • $match:过滤数据,只输出满足条件的文档
  • $group:将集合中的文档分组,用于统计结果
  • $project:修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
  • $sort:将输入文档排序后输出
  • $skip:跳过指定数量的文档,并返回余下的文档
  • $limit:限制通过该阶段的文档数
  • $unwind:将数组类型的字段拆分

$group会根据_id后面的字段进行分组,取字段的值的时候需要用$运算符

db.collection.aggregate([
   {`$match`:{`field`:value}},
   {`$group`:{'_id':field,count:{`$sum`:1},'avg_age':{'$avg':'$age'}}},
   {`$project`:{'cate':'_id','counter':'$count','_id':0,'avg_age':1,}},
])

$group还可以根据多个字段进行分组

db.collection.aggregate([
   {$group:{'_id':{'country':'$country','city':'$city'}}},
   ## 分组之后的结果是{_id:{country:value,city:value}}
   ## 取字典嵌套的字段的值,可以用`_id.country`,`_id.city`
   {$group:{'_id':{'country':'$_id.country','city':'$_id.city'},'count':{$sum:1}}},
   {$project:{'country':'$_id.country','city':'$_id.city','_id':0}}
])

$group的另一种用法:用于统计所有文档

db.collection.aggregate([
   {`$match`:{`field`:value}},
   {`$group`:{'_id':null,count:{`$sum`:1},'avg_age':{'$avg':'$age'}}},
])

$sort可对多个字段进行排序

db.collection.aggregate([
   {$sort:{field1:1,field2:-1}}
])

$unwind将文档中某数组类型的字段拆分成多条,每条包含数组中的一个值

db.t.insertOne({'_id':1,'item':'t-shirt',`size`:['S','M','L']})
db.t.aggregate([
   {$unwind:'$size'},
])

结果为:

{'_id':1,'item':'t-shirt','size':'S'}
{'_id':1,'item':'t-shirt','size':'M'}
{'_id':1,'item':'t-shirt','size':'L'}

Notice:在默认情况下,使用$unwind对数组字段展开时,会自动忽略null和空数组,
如果想要保留null和空数组,可以设置参数preserveNullAndEmptyArrays为true。
db.collection.aggregate({$unwind:{path:'$field',preserveNullAndEmptyArrays:true}})

explain():可用于查看命令执行的详细情况,输出的信息详细级别依次为:queryPlanner(默认),executionStatsallPlanExecution
db.collection.explain('executionStats').find()

MongoDB 原子操作常用命令

$set: 用来指定一个键并更新键值,若该键不存在,就创建该键
{$set:{field:value}}

$inc:对文档的某个数字类的键进行增减操作
{$inc:{field:value}}

$push:把value追加到field里面,field一定要是数组类型才行,如果field不存在,会新增加一个数组类型进去。
{$push:{field:value}}

$pushAll:同$push,只是一次可以追加多个值到一个数组字段内。
{$pushAll:{field:value_array}}

$pull:从数组field内删除一个等于value的值
{$pull:{field:_value}}

$pop:删除数组的第一个或最后一个元素
{$pop:{field:1}}

$rename:修改字段名称
{$rename:{old_field_name:new_field_name}}

正则表达式

MongoDB使用$regex操作符来设置匹配字符串的正则表达式。
使用正则表达式之前不需要做任何配置。
考虑以下文档:

{
   "post_text": "enjoy the mongodb articles on runoob",
   "tags": [
      "mongodb",
      "runoob"
   ]
}

使用正则表达式查找 post_text 包含 Runoob 字符串的文章

db.posts.find({post_text:{$regex:'Runoob'}})
db.posts.find({post_text:/Runoob/})
## 查找以enjoy开头
db.posts.find({post_text:/^enjoy/})
## 查找以runoob结尾
db.posts.find({post_text:/Runoob$/})

如果需要检索不区分大小写,可以设置$options为$i

以下命令将查找不区分大小写的字符串runoob
db.posts.find({post_text:{$regex:"runoob",$options:"$i"}})

优化正则表达式查询

  • 如果文档中设置了索引,那么使用索引相比于正则表达式匹配查找所有的数据查询速度更快。
  • 如果正则表达式是前缀表达式,所有匹配的数据将以指定的前缀字符串开始;

MongoDB 固定集合 (Capped Collection)

MongoDB 固定集合是性能出色,且有着固定大小的集合,就像一个环形队列,当集合空间用完之后,再插入的元素就会覆盖最初始的元素。

Notice: 固定集合无法使用remove()函数删除部分文档,但是可以删除全部文档

创建固定集合
db.createCollection('cappedCollection',{capped:true,size:maxSize,max:maxNum})
其中:size是整个集合空间的大小,单位是KB;
max是集合文档个数的上限,单位是'个';
如果空间大小达到上限,插入新文档的时候,会覆盖第一个文档;
如果文档个数到达上限,插入新文档的时候,同样会覆盖第一个文档。

判断一个集合是否为固定集合:
db.collection.isCapped()

如果需要将一个已经存在的集合转换为固定集合,可以使用:
db.runCommand({'convertToCapped':collection,size:value})

固定集合的属性

  • 对固定集合进行插入数据,速度极快
  • 按照插入顺序的查询,输出速度极快
  • 能够在插入最新数据时,淘汰最早的数据

常用用途

  • 存储日志信息
  • 缓存一些少量的文档

相关文章

网友评论

    本文标题:MongoDB 学习笔记

    本文链接:https://www.haomeiwen.com/subject/dsdnxhtx.html