mongoDB 初级学习笔记

什么是NoSQL?

NoSQL,指的是非关系型的数据库(Not only sql)。
没有行、列的概念。用 JSON 来存储数据。集合就相当于 SQL 数据库中的“表”,文档就相当于“行”。

  • 数据模型比较简单;
  • 需要灵活性更强的IT系统;
  • 对数据库性能要求较高;
  • 不需要高度的数据一致性;
  • 对于给定key,比较容易映射复杂值的环境。

NoSQL有哪些

memcache、mongodb、redis、ElasticSearch、hbase、PostgreSQL等

mongodb和传统关系型数据库的应用场景区别

mongodb适合做原始数据的归档,以备供大量数据查询。而高级的统计、汇总之类的,mongodb支持相对较弱。事物处理能力低。

mongodb 和 redis

mongo存放东西是放在硬盘上的,redis是放在内存里面的,当然redis也会定期持久化到磁盘上,mongo比较适合大数据,redis适合数据量小,但是效率要求很高的场合。

基本概念

部署安装

  • 官网下载tar包,解压后即可使用绿色软件。

  • 配置文件,新建etc/mongodb.conf:

dbpath=/data/mongodb/master
logpath=/data/mongodb/log/master.log
master=true
fork=true
port=27017
oplogSize=2048

配置文件常用选项:
--dbpath 指定数据库的目录。
--port 指定数据库端口,模式是27017。
--bind_ip 绑定IP。
--derectoryperdb为每个db创建一个独立子目录。
--logpath 指定日志存放目录。
--logappend 指定日志生成方式(追加/覆盖)。
--pidfilepath 指定进程文件路径,如果不指定,将不产生进程文件。
--keyFile 集群模式的关键标识
--journal 启用日志
--nssize 指定.ns文件的大小,单位MB,默认是16M,最大2GB。
--maxConns 最大的并发连接数。
--notablescan 不允许进行表扫描
--noprealloc 关闭数据文件的预分配功能
--fork 以后台Daemon形式运行服务

  • 添加环境变量
export PATH=<mongodb-install-directory>/bin:$PATH
  • 启动
mongod -f /usr/local/mongodb/etc/mongodb.conf

启动后可以通过mongo命令连接到数据库

数据库基本操作

  • 查看数据库
    show dbs
> show dbs
admin  0.000GB
local  0.000GB
test   0.000GB
  • 切换和创建数据库
    use db (如果存在则切换如果不存在则创建)
> use admin
switched to db admin
  • 删除数据库
    db.dropDatabase()
> use test
switched to db test
> db.dropDatabase()
{ "dropped" : "test", "ok" : 1 }
> show dbs
admin  0.000GB
local  0.000GB
  • 创建集合(相当于关系型数据库中的表)写入文档
    db.collectionname.insert({json内容})
> use test
switched to db imooc
> db.test_collection.insert({name:"jihaitao"})
WriteResult({ "nInserted" : 1 })
  • 查询集合
    show collections
> show collections
test_collection
  • 查询集合内容
> db.test_collection.find()
{ "_id" : ObjectId("5a17bda0cd1d754638319399"), "name" : "jihaitao" }
> db.test_collections.find({"name":"jihaitao"})
{ "_id" : ObjectId("5a17bda0cd1d754638319399"), "name" : "jihaitao" }

_id是mongoDB自己生成的字段全局唯一字段,_id可以在插入数据时自己指定,但是不能跟已有的_id重复。

> db.test_collections.insert({name:"sky",_id:12345})
WriteResult({ "nInserted" : 1 })
> db.test_collections.find()
{ "_id" : ObjectId("5a17be74cd1d75463831939a"), "name" : "jihaitao" }
{ "_id" : 12345, "name" : "sky" }
  • 一些查询选项
先插入多个字段

> for(i=3;i<50;i++)db.test_collections.insert({x:i})
WriteResult({ "nInserted" : 1 })
> db.test_collections.find()
{ "_id" : ObjectId("5a17c17960660ca23324fb88"), "name" : "jihaitao" }
{ "_id" : ObjectId("5a17c31960660ca23324fb89"), "x" : 3 }
{ "_id" : ObjectId("5a17c31960660ca23324fb8a"), "x" : 4 }
{ "_id" : ObjectId("5a17c31960660ca23324fb8b"), "x" : 5 }
{ "_id" : ObjectId("5a17c31960660ca23324fb8c"), "x" : 6 }
{ "_id" : ObjectId("5a17c31960660ca23324fb8d"), "x" : 7 }
{ "_id" : ObjectId("5a17c31960660ca23324fb8e"), "x" : 8 }
{ "_id" : ObjectId("5a17c31960660ca23324fb8f"), "x" : 9 }
{ "_id" : ObjectId("5a17c31960660ca23324fb90"), "x" : 10 }
{ "_id" : ObjectId("5a17c31960660ca23324fb91"), "x" : 11 }
{ "_id" : ObjectId("5a17c31960660ca23324fb92"), "x" : 12 }
{ "_id" : ObjectId("5a17c31960660ca23324fb93"), "x" : 13 }
{ "_id" : ObjectId("5a17c31960660ca23324fb94"), "x" : 14 }
{ "_id" : ObjectId("5a17c31960660ca23324fb95"), "x" : 15 }
{ "_id" : ObjectId("5a17c31960660ca23324fb96"), "x" : 16 }
{ "_id" : ObjectId("5a17c31960660ca23324fb97"), "x" : 17 }
{ "_id" : ObjectId("5a17c31960660ca23324fb98"), "x" : 18 }
{ "_id" : ObjectId("5a17c31960660ca23324fb99"), "x" : 19 }
{ "_id" : ObjectId("5a17c31960660ca23324fb9a"), "x" : 20 }
{ "_id" : ObjectId("5a17c31960660ca23324fb9b"), "x" : 21 }
Type "it" for more
查询条数

> db.test_collections.find().count()
48
其他选项

> db.test_collections.find().skip(3).limit(3).sort({x:1})
{ "_id" : ObjectId("5a17c31960660ca23324fb8b"), "x" : 5 }
{ "_id" : ObjectId("5a17c31960660ca23324fb8c"), "x" : 6 }
{ "_id" : ObjectId("5a17c31960660ca23324fb8d"), "x" : 7 }
  • 数据更新
    db.test_collections.update({匹配的数据},{替换的数据})
> db.test_collections.find({x:10})
{ "_id" : ObjectId("5a17c31960660ca23324fb90"), "x" : 10 }
> db.test_collections.update({x:10},{x:999})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.test_collections.find({x:10})
> db.test_collections.find({x:999})
{ "_id" : ObjectId("5a17c31960660ca23324fb90"), "x" : 999 }

部分更新

> db.test_collections.insert({x:100,y:100,z:100})
WriteResult({ "nInserted" : 1 })
> db.test_collections.update({x:100},{y:99})

#上面这个情况会把 {x:100,y:100,z:100} 整体替换成{y:99} 而不是只替换y。正确的方法是:

> db.test_collections.update({x:100},{$set:{y:99}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.test_collections.find({x:100})
{ "_id" : ObjectId("5a17c86160660ca23324fbb8"), "x" : 100, "y" : 99, "z" : 100 }

更新不存在的数据

> db.test_collections.update({y:100},{y:999})
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
> db.test_collections.find({y:100})
> db.test_collections.find({y:999})
可以看到失败了
> db.test_collections.update({y:100},{y:999},true)
WriteResult({
    "nMatched" : 0,
    "nUpserted" : 1,
    "nModified" : 0,
    "_id" : ObjectId("5a17caec37dea190b750a188")
})
> db.test_collections.find({y:999})
{ "_id" : ObjectId("5a17caec37dea190b750a188"), "y" : 999 }

update默认更新匹配到的第一条数据,如何更新多条数据?

#我们先插入3条c:1的数据
> db.test_collections.insert({c:1})
WriteResult({ "nInserted" : 1 })
> db.test_collections.insert({c:1})
WriteResult({ "nInserted" : 1 })
> db.test_collections.insert({c:1})
WriteResult({ "nInserted" : 1 })

#查询一下共3条
> db.test_collections.find({c:1})
{ "_id" : ObjectId("5a17cc7060660ca23324fbb9"), "c" : 1 }
{ "_id" : ObjectId("5a17cc7160660ca23324fbba"), "c" : 1 }
{ "_id" : ObjectId("5a17cc7260660ca23324fbbb"), "c" : 1 }

#update一下看看,可以看到更新了一条还有2条c:1
> db.test_collections.update({c:1},{c:2})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.test_collections.find({c:1})
{ "_id" : ObjectId("5a17cc7160660ca23324fbba"), "c" : 1 }
{ "_id" : ObjectId("5a17cc7260660ca23324fbbb"), "c" : 1 }
> db.test_collections.find({c:2})
{ "_id" : ObjectId("5a17cc7060660ca23324fbb9"), "c" : 2 }

#update第四个参数muti,默认是false。当它为true的时候,update方法会首先查找与第一个参数匹配的记录。因此设成true即可。

> db.test_collections.update({c:1},{$set{c:2}},false,true)
2017-11-23T23:46:50.494-0800 E QUERY    [thread1] SyntaxError: missing : after property id @(shell):1:38
> db.test_collections.update({c:1},{$set:{c:2}},false,true)
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })
> db.test_collections.find({c:1})
> db.test_collections.find({c:2})
{ "_id" : ObjectId("5a17cc7060660ca23324fbb9"), "c" : 2 }
{ "_id" : ObjectId("5a17cc7160660ca23324fbba"), "c" : 2 }
{ "_id" : ObjectId("5a17cc7260660ca23324fbbb"), "c" : 2 }
  • 数据删除

删除字段
db.test_collections.remove({json})

> db.test_collections.find({c:2})
{ "_id" : ObjectId("5a17cc7060660ca23324fbb9"), "c" : 2 }
{ "_id" : ObjectId("5a17cc7160660ca23324fbba"), "c" : 2 }
{ "_id" : ObjectId("5a17cc7260660ca23324fbbb"), "c" : 2 }
> db.test_collections.remove({c:2})
WriteResult({ "nRemoved" : 3 })
> db.test_collections.find({c:2})

删除集合

> db.test_collections.drop()
true
> show collections
> 

索引

mangodb中如果数据很多,根据指定条件查询会不返回值,这时候需要将指定值设置为索引。添加索引会提高查询效率。

  • 查询索引
> db.test_collections.getIndexes()
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "test.test_collections"
    }
]
  • 添加x字段为集合的索引(如数据量较大需要消耗一定时间)
> db.test_collections.ensureIndex({x:1})
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}
  • 索引类型


备份与恢复

  • 备份
    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目录,这个目录里面存放该数据库实例的备份数据。

[root@vm172-26-0-15 mongodb]# mongodump -h 127.0.0.1 -d test -o /tmp/
2017-11-28T15:22:25.985+0800    writing test.test_collections to 
2017-11-28T15:22:25.987+0800    done dumping test.test_collections (47 documents)
[root@vm172-26-0-15 mongodb]# cd /tmp/
[root@vm172-26-0-15 tmp]# ls
index.html  mongodb-27017.sock  Python-3.6.3  test
  • 恢复
    mongorestore -h <hostname><:port> -d dbname <path>

--host <:port>, -h <:port>:
MongoDB所在服务器地址,默认为: localhost:27017
--db , -d :
需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
--drop:
恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用哦!
<path>:
mongorestore 最后的一个参数,设置备份数据所在位置,例如:c:\data\dump\test。
你不能同时指定 <path> 和 --dir 选项,--dir也可以设置备份目录。
--dir:
指定备份的目录
你不能同时指定 <path> 和 --dir 选项。

#先删除test数据库
> use test
switched to db test
> db.dropDatabase()
{ "dropped" : "test", "ok" : 1 }

#然后退出mongo
[root@vm172-26-0-15 test]# mongorestore -h 127.0.0.1:27017 -dir /tmp/test
2017-11-28T16:18:05.157+0800    the --db and --collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use --nsInclude instead
2017-11-28T16:18:05.158+0800    building a list of collections to restore from /tmp/test dir
2017-11-28T16:18:05.158+0800    reading metadata for ir.test_collections from /tmp/test/test_collections.metadata.json
2017-11-28T16:18:05.164+0800    restoring ir.test_collections from /tmp/test/test_collections.bson
2017-11-28T16:18:05.166+0800    restoring indexes for collection ir.test_collections from metadata
2017-11-28T16:18:05.171+0800    finished restoring ir.test_collections (47 documents)
2017-11-28T16:18:05.171+0800    done

#再看一下数据库是否恢复
> show dbs
admin  0.000GB
local  0.000GB
test   0.000GB

在程序中中使用mongoDB

  • eg:python
from pymongo import MongoClient
conn = MongoClient('192.168.0.113', 27017)
db = conn.mydb  #连接mydb数据库,没有则自动创建
my_set = db.test_set  #使用test_set集合,没有则自动创建

#插入数据
my_set.insert({"name":"zhangsan","age":18})
#或
my_set.save({"name":"zhangsan","age":18})

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

推荐阅读更多精彩内容