MongoDB 基础(2019年开篇)

自作多情 提交于 2020-03-26 08:52:32

MongoDB基础知识:

1、什么是MongoDB
 NoSQL(NoSQL=Not Only SQL),意即"不仅仅是SQL"。
 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
 
 MongoDB是由C++编写的,MongoDB语法类似JS,是一个基于分布式文件存储的开源数据库系统。
 在高负载的情况下,添加更多的节点,可以保证服务器性能。
 MongoDB旨在为WEB应用提供可扩展的高性能数据存储解决方案。
 MongoDB将数据存储为一个文档,数据结构由键值对(key=>value)组成。MongoDB文档类似于JSON对象。字段值可以包含其他文档,数组及文档数组。

 示例:
 {
    name: "wangchunwang",
    age: 26,
    groups: ["news", "sports"]
 }
 假设上述文档所在的集合是testcoll,那么以下几种查询键值方法等效:
   > db.testcoll.findOne().name            // 点链式访问
   > db["test"].findOne()["name"]        // 数组式访问

2、进入MongoDB Shell
 在cmd中输入 > mongo [ip:port/database -u username -p]

 查看当前操作的数据库:> db
 显示所有数据库:> show dbs
 连接到指定的数据库:> use db_name        // 不存在,则新建之

 有一些数据库名是保留的:
 admin:从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
 local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合。
 config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
 
 创建用户(用户是基于数据库的):
 > use test        // 先切换到某个数据库,再创建用户
 > db.createUser({
    user: "root",
    pwd: "root",
    roles: [{ role: "dbAdmin", db: "test" }]    // 常用角色:read、readWrite、dbAdmin、root / readAnyDatabase、readWriteAnyDatabase、dbAdminAnyDatabase
    })
    
 修改用户密码:> db.changeUserPassword(username, password)
 授权用户角色:> db.grantRolesToUser(username, roles [,writeConcern])
 删除用户:
    > use test      // 需要先切换到该数据库,否则删除不成功
    > db.dropUser(username)

3、Mongo中的一些概念
--------------+------------------------+-------------------------------------------
 SQL术语/概念    MongoDB术语/概念         解释/说明
--------------+------------------------+-------------------------------------------
 database            database                数据库
--------------+------------------------+-------------------------------------------
 table                collection                数据库表/集合
--------------+------------------------+-------------------------------------------
 row                document                数据记录行/文档
--------------+------------------------+-------------------------------------------
 column                field                    数据字段/域
--------------+------------------------+-------------------------------------------
 index                index                    索引
--------------+------------------------+-------------------------------------------
 table                 joins                     表连接,MongoDB不支持
--------------+------------------------+-------------------------------------------
 primary key        primary key                主键,MongoDB自动将"_id"字段设置为主键
--------------+------------------------+-------------------------------------------

 ObjectId:类似唯一主键,包含12个字节:
 前4个字节表示创建unix时间戳,接下来的3个字节是机器标识码,紧接的2个字节是进程id,最后3个字节是随机数。

 由于ObjectId中保存了创建的时间戳,所以你不需要为你的文档保存时间戳字段,可以通过"getTimestamp()"来获取文档的创建时间戳:
   ObjectId("5c263a0a1968ec6c090e57fd").getTimestamp()        // 返回时间戳
   ObjectId("5c263a0a1968ec6c090e57fd").str                    // 返回字符串

 MongoDB无须声明数据类型,全自动匹配。

4、创建数据库
 > use db_name
 名称通常小写。
 MongoDB中默认的数据库为test,如果你没有创建新的数据库,集合将存放在test数据库中。

5、删除数据库
 首先连接到要删除的数据库:
 > use db_name
 > db.dropDatabase()
 
6、创建集合
 > db.createCollection(name [,options])
 名称通常小写。
 options参数说明:
   capped:如果为 true 或 1 ,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。
   size:当capped为true时须指定该参数值,固定集合最大值。单位:KB。
   max:可选,固定集合最大文档数。单位:个。
   
7、删除集合
 > db.collection_name.drop()

8、插入文档
 > db.collection_name.insert({key: value, ...})
 文档的数据结构和JSON基本一样。

9、更新文档
 > db.collection_name.update(query, update [,options])
 参数说明:
   query:查询条件。例{name: "wangchunwang"}。
   update:更新操作符(如$set,$unset,$inc等原子操作,$unset是移除键值对)。例{$set: {name: "wcwnina"}}、{$unset: {salary: 1}}。
   options参数说明:
     upsert:布尔型,查无结果是否插入文档。默认false。
     multi:布尔型,是否更新全部查询结果。默认false。

 > db.collection_name.save(document)        // 替换整个文档
 
10、删除文档
 > db.collection_name.remove([query, options])
 参数说明:
   query:查询条件。
   options参数说明:
     justOne:布尔型,是否只删除一条。默认false。
     
11、查询文档
 > db.collection_name.find([query, projection])
  参数说明:
    query:查询条件。
    projection:返回指定的键,true或1返回,false或0不返回。例{name: 1, salary: 1}。
 
 格式化显示结果:
   > db.collection_name.find().pretty()
 
 AND条件:
   MongoDB的find()方法可以传入多个键,每个键以逗号隔开,即常规SQL的AND条件。
 OR条件:
   MongoDB的OR条件语句使用了操作符$or。如:> db.collection_name.find({$or: [{key1: value1}, {key2: value2}]})

 关系比较符:
   小于:$lt
   小于或等于:$lte
   大于:$gt
   大于或等于:$gte
   不等于:$ne
   属于:$in
   例> db.collection_name.find({salary: {$lt: 10000, $gt: 5000}})。        // 5000<salary<10000
 
 模糊查询:使用JS正则表达式。
   > db.collection_name.find({name: /wangchunwang/})        // 包含
   > db.collection_name.find({name: /^wangchunwang/})        // 以...开头
   > db.collection_name.find({name: /wangchunwang$/})        // 以...结尾
   
 limit(number)方法:限制读取文档数量。
 skip(number)方法:开头跳过的文档数量。效率很差,影响查询速率。
 skip()和limit()组合能实现分页。
 例> db.collection_name.find().skip(1).limit(10)    // 跳过第一个,从第二个开始,查询10个文档
 
 排序sort():
   > db.collection_name.find().sort({key: 1或-1})    // 1升序,-1降序
   
 总结:skip(),limilt(),sort()三个放在一起执行的时候,执行的顺序是先sort(),然后是skip(),最后是显示的limit()。

12、创建索引
 索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。这种扫描全集合的查询效率是非常低的。
 索引可以级联,即可以为子文档的键创建索引。
 
 > db.collection_name.createIndex({key: 1或-1} [,options])    // 1升序索引,-1降序索引
 options参数说明:
   name:索引的名称。如果未指定,通过连接索引的键名和排序顺序生成一个索引名称。
   unique:建立的索引是否唯一。若为true或1则创建唯一索引,那么该键的值唯一。默认值为false。
   
 查看集合索引:
   > db.collection_name.getIndexes()
 查看集合索引大小:
   > db.collection_name.totalIndexSize()
 删除集合指定索引:
   > db.collection_name.dropIndexes(index_name)
 删除集合所有索引:
   > db.collection_name.dropIndex()
   
13、聚合
 MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。
 
 > db.collection_name.aggregate(operations)
 $sum    计算总和。
 $avg    计算平均值。
 $max    获取集合中所有文档对应值的最大值。
 例> db.collection_name.aggregate({$group: {_id: 0, total: {$sum: "$salary"}}})        // _id的值为分组依据,total为自定义键,$为引用某个键
 
14、MongoDB复制(replSet)
 MongoDB复制是将数据【实时】同步在多个服务器上。
 MongoDB复制需要主从节点,主节点负责处理客户端请求,其余都是从节点,负责复制主节点上的数据。
 各个节点常见的搭配方式为:一主一从、一主多从。
 
 副本集特征:
   a)N个节点的集群;
   b)所有写入操作都在主节点上;
   c)主从实时复制,任何节点可作为主节点;
   d)自动故障转移和恢复,高可用性。
 
 具体操作(略)
 
15、MongoDB分片(shard)
 在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求。
 三个主要组件:
   Shard:用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组一个replica set承担,防止主机单点故障
   Config Server:mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。
   Query Routers:前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。

16、MongoDB备份(mongodump)与恢复(mongorestore)
 备份:使用mongodump命令导出所有数据到指定目录中。
   > mongodump -h host -p port -d db_name -o bakdir
   例:mongodump -h 127.0.0.1 -p 27017 -d test -o E:\bakdata
 参数说明:
   -h:MongDB所在服务器IP。
   -p:MongDB所在服务器端口。
   -d:需要备份的数据库实例。
   -o:备份的数据存放位置。
 
 恢复:使用mongorestore命令来导入备份的数据。
  > mongorestore -h host -p port -d db_name bakpath
  例:mongorestore -h 127.0.0.1 -p 27017 -d test E:\bakdata\test
 
17、MongoDB监控
 MongoDB中提供了mongostat和mongotop两个命令来监控MongoDB的运行情况。
 mongostat [seconds]命令:状态检测工具。
 mongotop [seconds]命令:每个集合的读写时间统计。
 
18、MongoDB查询分析
 询分析常用函数:explain()
 > db.collection_name.find({name: "wangchunwang"}).explain()
 
19、MongoDB关系
 引用式关系是设计数据库时经常用到的方法,通过引用文档的_id字段来建立关系。
 
 例{
     adress_id: {
        $ref: "collection_name",                    // 引用的集合
        $id: ObjectId("5c263a0a1968ec6c090e57fd"),    // 引用的文档_id
        $db: "db_name"                                // 引用的数据库
     }
    }
 
19、原子操作常用命令
 $set
   用来指定一个键并更新键值,若键不存在并创建。
   { $set: { key: value } }
 
 $unset
   用来删除一个键。
   { $unset: { key: 1} }
 
 $inc
   对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作。
   { $inc: { key: value } }
 
 $push
   把value追加到key里面去,key一定要是"数组"类型才行,如果key不存在,会新增一个"数组"类型加进去。
   { $push: { key: value } }
 
 $pull
   从"数组"key内删除一个等于value值。
   { $pull: { key: value } }
 
 $addToSet
   增加一个值到"数组"内,而且只有当这个值不在"数组"内才增加(不重复增加)。
 
 $pop
   删除"数组"的最后一个或第一个元素。
   { $pop: { key: 1 } }        // 1是最后一个,-1是第一个
 
 $rename
   修改键名称。
   { $rename: { old_key_name: "new_key_name" } }
 
20、MapReduce
 详见:https://www.cnblogs.com/wcwnina/p/9494706.html
 
21、全文索引
 给文档的多个键建立text全文索引后,就可以在整个集合中根据关键字搜索出文档。
 关键字是单词,对中文支持很差。
 
 创建全文索引:
 > db.collection_name.createIndex({key1: "text", key2: "text"})
 使用全文索引:
 > db.collection_name.find({$text: {$search: "keyword1 keyword2"})         // 多个关键字用空格或逗号隔开
 
22、正则表达式
 正则表达式是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。与JS正则表达式语法一致。
 
 直接使用正则表达式:
 > db.collection_name.find({key: {$regex: /mongo/i})    // 采用$regex操作符。i忽略大小写,m多行匹配
 以上查询也可以写为:
 > db.collection_name.find({key: /mongo/i})                // 直接采用JS正则表达式

 

待续。。。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!