mongoDB学习笔记

mongoDB简介

MongoDB是用C++语言编写的非关系型数据库。特点是高性能、易部署、易使用,存储数据十分方便,主要特性有:
面向集合存储,易于存储对象类型的数据
模式自由
支持动态查询
支持完全索引,包含内部对象
支持复制和故障恢复
使用高效的二进制数据存储,包括大型对象
文件存储格式为BSON(一种JSON的扩展)

mongoDB 概念

image.png
1.database 数据库

多个集合逻辑上组织在一起,就是数据库。

数据库命名规范:

  • 不能是空字符串("")。
  • 不得含有' '(空格)、.、$、/、\和\0 (空字符)。
  • 应全部小写。
  • 最多64字节。

有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。

  • admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
  • local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
  • config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
2. collection 集合

多个文档组成一个集合,相当于关系数据库的表。

所有存储在集合中的数据都是 BSON 格式,BSON 是类 JSON 的一种二进制形式的存储格式,简称 Binary JSON。

集合名命名规范:

  • 集合名不能是空字符串""。
  • 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
  • 集合名不能以"system."开头,这是为系统集合保留的前缀。
  • 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。


    image.png
3. document 文档

MongoDB 将数据存储为一个文档,数据结构由键值对组成。

MongoDB 文档是一组键值对(即BSON,二进制的 JSON),类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

文档键命名规范:

  • 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
  • .和$有特别的意义,只有在特定环境下才能使用。
  • 以下划线"_"开头的键是保留的(不是严格要求的)。

需要注意的是:

  • 文档中的键值对是有序的。
  • 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
  • MongoDB区分类型和大小写。
  • MongoDB的文档不能有重复的键。
  • 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
4.mongoDB - 数据类型

ObjectId:主键,一种特殊而且非常重要的类型,每个文档都会默认配置这个属性,属性名为_id,除非自己定义,方可覆盖

image.png

mongoDB命令

1.创建数据存储目录

mongoDB将目录存储在db目录下,需手动创建。

 /Users/mrotaku/Desktop
2.开启mongoDB的服务器

dbpath指定数据的存放位置,port指定端口号,关闭服务:ctrl + c

mongod --dbpath=/Users/mrotaku/Desktop/nosql --port 27017
3.数据库常用命令

连接指定mongoDB

ctrl+c 关闭连接

mongo localhost:27017

查看当前数据库

db

查看所有数据库

mongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。

show dbs

连接指定数据库

如果数据库不存在,则创建数据库,否则切换到指定数据库。

use db_name

查看服务器状态

db.serverStatus()

查看数据库统计信息

db.stats()

删除数据库

db.dropDatabase()

查看数据库中所有集合

show collections
或
show tables

清空集合

删除里面的文档,但集合还在

db.db_name.romve({})

删除集合

db.db_name.drop()

查看集合详细信息

db.db_name.find(key,value).explain("allPlansExecution")

mongoDB的增删查改

1.添加

mongoDB使用insert()或者save()的方法向集合中插入数据

如果该集合不在该数据库中, MongoDB 会自动创建该集合并插入文档。

insert() 或 save() 方法都可以向collection里插入数据,两者区别:

  • 如果不指定 _id 字段,save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。

  • 使用save函数,如果原来的对象不存在,那他们都可以向collection里插入数据,如果已经存在,save会调用update更新里面的记录,而insert则会忽略操作

  • insert可以一次性插入一个列表,而不用遍历,效率高, save则需要遍历列表,一个个插入。

例如向col集合中插入一条数据:

db.col_1.insert({
    name:'zhangsan',
    age:23,
    phone:1877768121
})

第二种方式:

document = ({
    name:'lisi',
    age:19,
    phone:15633577595
});

db.col_1.insert(document)
2.更新

mongoDB使用update语句更新集合中的文档

db.collection.update(criteria,objNew,upsert,multi)
参数说明:
criteria:用于设置查询条件的对象
objNew:用于设置更新内容的对象
upsert:如果记录已经存在,更新它,否则新增一个记录,取值为0或1
multi:如果有多个符合条件的记录,是否全部更新,取值为0或1

注意:默认情况下,只会更新第一个符合条件的记录
一般情况下后两个参数分别为0,1 ,即:
db.collection.update(criteria,objNew,0,1)

$set 操作符为部分更新操作符,只更新 $set 之后的数据,而不是覆盖之前的数据

-->将用户名称为"zhangsan"用户的年龄更改为18

db.col_1.update({name:'zhangsan'},{$set:{age:18}})

以上语句只会修改第一条发现的文档,如果要修改多条相同的文档,则需要设置 multi 参数为 true。

db.col_1.update({name:'zhangsan'},{$set:{age:18}},{multi:true})

更新集合中的文档,使用 $inc 将集合中name为user1的age加1,其它键不变, $inc表示使某个键值加减指定的数值

db.col_1.update({name:'zhangsan'},{$inc:{age:1}})
3.删除

remove() 函数是用来删除集合中的数据

在执行 remove() 函数前先执行 find() 命令来判断执行的条件是否正确,这是一个比较好的习惯。

删除集合中所有文档

db.col_1.romve({})

移除集合中查询到的数据的第一条

db.col_1.romve({name:'zhangsan'},1)
4.查询

db.col_name.find(query, projection)

  • query :可选,使用查询操作符指定查询条件
  • projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。

find()方法,查询返回集合中的所有文档

db.col_1.find()

findOne(),查询返回集合中的第一个文档

db.col_1.findOne()

格式化输出

db.col_1.find().pretty()

查询文档的个数

db.col_1.find().count()

跳过指定数量的数据

db.col_1.find().skip()

分页查询文档

db.col_1.find().limit();

想要读取从 10 条记录后 100 条记录,相当于 sql 中limit (10,100)。

db.col_1.find().skip(10).limit(100)

排序

sort()方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。

db.col_1.find().sort({key:1});
4.查询+where语句

如果你想获取"col"集合中 "likes" 大于100,小于 200 的数据,你可以使用以下命令:

db.col_1.find({likes : {$lt :200, $gt : 100}})

// 类似于SQL语句:
Select * from col where likes>100 AND  likes<200;
条件操作符 中文 全英文
$gt 大于 greater than
$gte 大于等于 greater than equal
$lt 小于 less than
$lte 小于等于 less than equal
$ne 不等于 not equal
5.AND 条件

find() 方法可以传入多个键(key),每个键(key)以逗号隔开,语法格式如下:

db.col_1.find({name:'zhangsan',age:18}).pretty()
6. OR 条件
db.col_1.find({$or:[{name:'zhangsan'},{age:20}]}).pretty()
7.AND 和 OR 联合使用
db.col_1.find({"likes":{$gt:50},$or:[{age:20},{phone:15633577595}]}).pretty()
7.$exists()

$exists,用于查询集合中存在某个键的文档或不存在某个键的文档,例如查询col_1集合中存在name键的所有文档

db.col_1.find({name:{$exists:1}})
8. $in和$nin

查询年龄在18,19,20在这个区间的文档

db.col_1.find({age:{$in:[18,19,20]}})

查询年龄不在18,19,20在这个区间的文档

db.col_1.find({age:{$nin:[18,19,20]}})

MongoDB - 索引

索引就是用来加速查询的。数据库索引与书籍的索引类似:有了索引就不需要翻遍整本书,数据库则可以直接在索引中查找,使得查找速度能提高几个数量级。在索引中找到条目以后,就可以直接跳转到目标文档的位置。

1. 查看索引

getIndexes 查看集合索引情况

db.col_1.getIndexes()

db.collection.stats() 查看索引状态

db.col_1.stats()
2. 创建索引

创建普通索引,使用命令 db.collection.ensureIndex({key:1})

db.col_1.ensureIndex({key:1})
3. 删除索引

删除索引(不会删除 _id 索引)

db.col_1.dropIndexes()

db.col_name.dropIndex({key: 1})
4. _id索引

对于每个插入的数据,都会自动生成一条唯一的 _id 字段,_id 索引是绝大多数集合默认建立的索引

> db.col_1.insert({x:10})
WriteResult({ "nInserted" : 1 })

> db.col_1.find()
{ "_id" : ObjectId("59658e56aaf42d1c98dd95a2"), "x" : 10 }

> db.col_1.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "runoob.col_1"
        }
]

字段解释:

  • v 表示 version,在 Mongo3.2 之前的版本中,会存在 {v:0}(版本锁为0)的情况。在3.2之后的版本中,{v:0} 不再允许使用,这部分可以不去关注,因为 v 由系统自动管理

  • key 表示作为索引的键。1 或 -1表示排序模式,1为升序,1为降序

  • name 表示索引的名字,默认生成名称的规则是作为索引的字段_排序模式

  • ns 表示 namespace 命名空间,由数据库名称.集合名称组成

5.多键索引

单键索引的值为一个单一的值,多键索引的值有多个数据(如数组)

如果mongoDB中插入数组类型的多键数据,索引是自动建立的,无需刻意指定

> db.col_1.insert({z:[1,2,3,4,5]})
WriteResult({ "nInserted" : 1 })

> db.col_1.find()
{ "_id" : ObjectId("59658e56aaf42d1c98dd95a2"), "x" : 10 }
{ "_id" : ObjectId("5965923eaaf42d1c98dd95a3"), "y" : 20 }
{ "_id" : ObjectId("59659828aaf42d1c98dd95a4"), "z" : [ 1, 2, 3, 4, 5 ] }

> db.col_1.find({z:3})
{ "_id" : ObjectId("59659828aaf42d1c98dd95a4"), "z" : [ 1, 2, 3, 4, 5 ] }
6.符合索引

同时对多个字段创建索引

> db.col_2.insert({x:10,y:20,z:30})
WriteResult({ "nInserted" : 1 })

> db.col_2.find()
{ "_id" : ObjectId("59659a57aaf42d1c98dd95a5"), "x" : 10, "y" : 20, "z" : 30 }

> db.col_2.createIndex({x:1,y:1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

> db.col_2.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "runoob.col_2"
        },
        {
                "v" : 2,
                "key" : {
                        "x" : 1,
                        "y" : 1
                },
                "name" : "x_1_y_1",
                "ns" : "runoob.col_2"
        }
]
7.全文索引

场景:全网站关键词搜索

key-value 中,key 此时为 $**(也可以是具体某 key),value 此时为一个固定的字符串(如 text)

全文索引相似度,与 sort 函数一起使用效果更好

db.col_1.find({ $text: { $search: "aa bb" } }, { score: { $meta: "textScore" } }).sort({ score: { $meta: "textScore" } })

注意:

  • 每个集合只能创建一个全文索引
  • MongoDB 从 2.4 版本开始支持全文检索,从 3.2 版本开始支持中文
    (好像)只能对整个单词查询,不能对单词的截取部分查询
  • 关键词之间的空格表示或
  • 关键词之前的 - 表示非
  • 关键词加引号表示与 (需用 \ 转义)

MongoDB - 备份与恢复

MongoDB提供了备份和恢复的功能,分别是MongoDB下载目录下的mongodump.exe和mongorestore.exe文件

备份数据库

备份数据使用下面的命令:

mongodump -h dbhost -d dbname -o dbdirectory
-h:MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
-d:需要备份的数据库实例,例如:test
-o:备份的数据存放位置,例如:c:\data\dump,当然该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。

mongodump -h 127.0.0.1:27017 -d hrabbit -o /Users/mrotaku/Desktop/dump
恢复数据库

恢复数据使用下面的命令:

mongorestore -h dbhost -d dbname -directoryperdb dbdirectory
-h:MongoDB所在服务器地址
-d:需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
-directoryperdb:备份数据所在位置,例如:c:\data\dump\test

mongorestore -h 127.0.0.1:27017 -d hrabbit -directoryperdb /Users/mrotaku/Desktop/dump
导出数据

导出数据可以使用命令:

mongoexport -h dbhost -d dbname -c collectionName -o output

参数说明:
-h 数据库地址
-d 指明使用的库
-c 指明要导出的集合
-o 指明要导出的文件名

mongoexport -h127.0.0.1:27017 -dhrabbit -c col_1 -o output
导入数据

导出数据可以使用命令:

mongoimport -h dbhost -d dbname -c collectionname 文件的地址...
参数说明:
-h 数据库地址
-d 指明使用的库
-c 指明要导入的集合
本地的文件地址...

 mongoimport -h 127.0.0.1:27017 -d hrabbit -c col_2  /Users/mrotaku/Desktop/dump/hrabbit/c1.bson

安全和认证

每个MongoDB实例中的数据库都可以有许多用户。如果开启了安全性检查,则只有数据库认证用户才能执行读或者写操作。
在认证的上下文中,MongoDB会将普通的数据作为admin数据库处理。admin数据库中的用户被视为超级用户(即管理员)。
在认证之后,管理员可以读写所有数据库,执行特定的管理命令,如listDatabases和shutdown。
在开启安全检查之前,一定要至少有一个管理员账号。

use admin;
db.addUser(“root”,”root”);

在col_1 中创建普通账号:

use col_1;
db.addUser(“zhangsan”,”123”);
db.addUser(“lisi”,”123”,true);

注意:用户lisi,密码为123,对col_1数据库拥有读写权限
用户zhangsan,密码为123,对col_1数据库拥有只读权限

重新启动数据库服务,并开启安全检查:

mongod --dbpath  /Users/mrotaku/Desktop/nosql --auth

接下来,将更新mongoDB的主从复制,待续……

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容