MongoDB

一、MongoDB是什么?

MongoDB是一款NoSQL数据库,与Redis一样都是非关系型数据库,NoSQL即表之间的各个数据之间互相独立,没有限定的表结构,可以完全拥有各自的结构。
MongoDB是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

二、MongoDB与关系型数据库的区别

比如:mysql的表tables,MongoDB这里叫集合collections,集合里面的每一条数据叫做文件(document)。

插入的不同数据拥有完全不用的键值对,这在关系型数据库中是做不到的。

三、一些基础操作指令

3.1 插入指令
> db.student.insert({"name":"xuye","school":"hafo","numbe":141420014}) 
  插入一条文档,我并没有创建集合student,直接写插入语句,如果表不存在会自动创建(一般都是使用此方式来建表,而不是去用createColletion()创建表,此方式的容量会自动增长。)
 
> db.student.insert({"class":101,"number":1401420,"teach":"xuye"})
在插入一条文档,可以发现,两条文档之间的格式要求是没有任何关系的,甚至你可以随便插入不是关于学生此类的信息都可以,但是一般一个表只插入一类信息的文档(约定成俗的)。
 
> db.student.find()      查看该集合中所有的文档。
{ "_id" : ObjectId("5b7d1aa979c725e3580ed2db") }
{ "_id" : ObjectId("5b7d1b1d79c725e3580ed2dc"), "name" : "xuye", "school" : "hafo", "numbe" : 141420014 }
{ "_id" : ObjectId("5b7d1c57c8ff91d6ecaf79d8"), "class" : 101, "number" : 1401420, "teach" : "xuye" }
此处还需要注意,我们并没有插入_id这个东西,这是mongodb自动帮我们生成的一个id,是唯一的,所以也就不需要我们去生成id了。
 
> db.student.find().pretty()
{ "_id" : ObjectId("5b7d1aa979c725e3580ed2db") }
{
        "_id" : ObjectId("5b7d1b1d79c725e3580ed2dc"),
        "name" : "xuye",
        "school" : "hafo",
        "numbe" : 141420014
} 格式化显示查询的语句,应该还有几条,我只取了其中一条粘贴在这里,就类似代码的格式化,好看一些。
 
> db.student.insert({"name":"xuye","number":140246,"deskmate":{"name":"xiaobai","number":140265}})
插入一条复杂一些的文档,可以嵌套,和json一样,只要符合键值对的形式都可以使用。如果多个嵌套的话,要使用中括号,如下。
 db.student.insert({"name":"xuye","number":140246,"deskmate":[{"name":"xiaobai","number":140265},
3.2 分页查询
> db.books.insert({"name":"spring","price":20.01})
> db.books.insert({"name":"springMvc","price":19.99})
> db.books.insert({"name":"java","price":67.84})
> db.books.insert({"name":"linux","price":289.78})
> db.books.insert({"name":"python","price":29.78})
> db.books.insert({"name":"c++","price":157.68})
先插入一些数据,书名和书的价格。
 
> db.books.find()
{ "_id" : ObjectId("5b7d4a588e6123a7a302be25"), "name" : "spring", "price" : 20.01 }
{ "_id" : ObjectId("5b7d4a6b8e6123a7a302be27"), "name" : "springMvc", "price" : 19.99 }
{ "_id" : ObjectId("5b7d4a7f8e6123a7a302be28"), "name" : "java", "price" : 67.84 }
{ "_id" : ObjectId("5b7d4a898e6123a7a302be29"), "name" : "linux", "price" : 289.78 }
{ "_id" : ObjectId("5b7d4a9f8e6123a7a302be2a"), "name" : "python", "price" : 29.78 }
{ "_id" : ObjectId("5b7d4aad8e6123a7a302be2b"), "name" : "c++", "price" : 157.68 }
查看数据,下面进行分页。
 
> db.books.find().skip(0).limit(3)
{ "_id" : ObjectId("5b7d4a588e6123a7a302be25"), "name" : "spring", "price" : 20.01 }
{ "_id" : ObjectId("5b7d4a6b8e6123a7a302be27"), "name" : "springMvc", "price" : 19.99 }
{ "_id" : ObjectId("5b7d4a7f8e6123a7a302be28"), "name" : "java", "price" : 67.84 }
分页查询,表示查到的数据,从第一条开始,显示3条。类似SQL的limit 0,3。也可以记为,跳过0条,显示3条。
 
> db.books.find().limit(3).skip(0)
{ "_id" : ObjectId("5b7d4a588e6123a7a302be25"), "name" : "spring", "price" : 20.01 }
{ "_id" : ObjectId("5b7d4a6b8e6123a7a302be27"), "name" : "springMvc", "price" : 19.99 }
{ "_id" : ObjectId("5b7d4a7f8e6123a7a302be28"), "name" : "java", "price" : 67.84 }
limit和skip两个函数可以更换位置,结果都一样。
 
> db.books.find().limit(3)  等同于db.books.find().skip(0).limit(3)
 
> db.books.find().skip(5)    跳过前5条,显示第六条以后的所有文档。
3.3 带条件的查询(and、or、gt、lt、正则、去重、排序等查询)
> db.books.find({"name":"spring"})
{ "_id" : ObjectId("5b7d4a588e6123a7a302be25"), "name" : "spring", "price" : 20.01 }
查询name为spring的书籍,在find函数的里面加上json格式的条件即可。
 
> db.books.find({"name":"spring","price":20.01})
{ "_id" : ObjectId("5b7d4a588e6123a7a302be25"), "name" : "spring", "price" : 20.01 }
多条件查询,使用逗号分隔即可,类似select * form books where name="spring" and price=20.01
 
> db.books.find({$or:[{"name":"spring"},{"name":"java"}]})
{ "_id" : ObjectId("5b7d4a588e6123a7a302be25"), "name" : "spring", "price" : 20.01 }
{ "_id" : ObjectId("5b7d4a7f8e6123a7a302be28"), "name" : "java", "price" : 67.84 }
查询nam为spring或者java的书籍,格式为find({$or : [{},{}]}) 中括号里面填写每一个json格式的条件,类似select * form books where name="spring" or name="java"
 
> db.books.find({"price":{$gte : 100}})
{ "_id" : ObjectId("5b7d4a898e6123a7a302be29"), "name" : "linux", "price" : 289.78 }
{ "_id" : ObjectId("5b7d4aad8e6123a7a302be2b"), "name" : "c++", "price" : 157.68 }
查询价格大于等于100的书籍。
 
> db.books.find({"price":{$lte : 20}})
{ "_id" : ObjectId("5b7d4a6b8e6123a7a302be27"), "name" : "springMvc", "price" : 19.99 }
查询价格小于等于20的书籍。
 
> db.books.find({"price":{$gte:100,$lte:200}})
{ "_id" : ObjectId("5b7d4aad8e6123a7a302be2b"), "name" : "c++", "price" : 157.68 }
查询价格大于等于100并且小于等于200的书籍。
 
> db.books.find({$or:[{"price":{$gt:200}},{"price":{$lt:20}}]})
{ "_id" : ObjectId("5b7d4a6b8e6123a7a302be27"), "name" : "springMvc", "price" : 19.99 }
{ "_id" : ObjectId("5b7d4a898e6123a7a302be29"), "name" : "linux", "price" : 289.78 }
查询价格大于200或者价格小于20的书籍,or的操作有点另类,一定要写在一开始的key上。
 
注意:gt为大于,gte为大于等于,lt为小于,lte为小于等于,e为equals。

因为带提交查询的指令内容太多,上面这一部分主要是大于和小于,and和or的指令。下面是去重,正则的条件查询。

> db.books.insert({"name":"spring","price":22.05})
先插入一条name同为spring的文档
 
> db.books.distinct("name")
[ "spring", "springMvc", "java", "linux", "python", "c++" ]
根据name去重,类似select distinct name from books
 
> db.books.distinct("name",{"price":{$lt:30}})
[ "spring", "springMvc", "python" ]
查询出价格小于30的书籍,然后根据name去重,类似select distinct name from books where price<30
distinct命令和find类似,只不过多了一个去重功能。
 
> db.books.find({"name":/spring/})
{ "_id" : ObjectId("5b7d4a588e6123a7a302be25"), "name" : "spring", "price" : 20.01 }
{ "_id" : ObjectId("5b7d4a6b8e6123a7a302be27"), "name" : "springMvc", "price" : 19.99 }
{ "_id" : ObjectId("5b7d58deabdfa1fbe797fa0b"), "name" : "spring", "price" : 22.05 }
使用正则表达式查询,/等同于%,类似select *from books where name like %spring%
 
> db.books.find({"name":/spring/}).skip(1).limit(2)
{ "_id" : ObjectId("5b7d4a6b8e6123a7a302be27"), "name" : "springMvc", "price" : 19.99 }
{ "_id" : ObjectId("5b7d58deabdfa1fbe797fa0b"), "name" : "spring", "price" : 22.05 }
搜索后的分页查询,在搜索栏输入内容后的查询功能,类似select *from books where name like %spring% limit 1,2。正则表达式内容较多,具体可自己网上查询。
 
> db.books.find({},{"price":1})
{ "_id" : ObjectId("5b7d4a588e6123a7a302be25"), "price" : 20.01 }
{ "_id" : ObjectId("5b7d4a6b8e6123a7a302be27"), "price" : 19.99 }
{ "_id" : ObjectId("5b7d4a7f8e6123a7a302be28"), "price" : 67.84 }
{ "_id" : ObjectId("5b7d4a898e6123a7a302be29"), "price" : 289.78 }
{ "_id" : ObjectId("5b7d4a9f8e6123a7a302be2a"), "price" : 29.78 }
{ "_id" : ObjectId("5b7d4aad8e6123a7a302be2b"), "price" : 157.68 }
{ "_id" : ObjectId("5b7d58deabdfa1fbe797fa0b"), "price" : 22.05 }
只显示price列,格式find({},{key1:1,key2:1}),第一个{}表示查询的条件,第二个为显示的列信息,多个用逗号隔开,类似select price from books,但是_id它是必须显示的。
 
> db.books.find({},{"price":1}).sort({"price":1})
{ "_id" : ObjectId("5b7d4a6b8e6123a7a302be27"), "price" : 19.99 }
{ "_id" : ObjectId("5b7d4a588e6123a7a302be25"), "price" : 20.01 }
{ "_id" : ObjectId("5b7d58deabdfa1fbe797fa0b"), "price" : 22.05 }
{ "_id" : ObjectId("5b7d4a9f8e6123a7a302be2a"), "price" : 29.78 }
{ "_id" : ObjectId("5b7d4a7f8e6123a7a302be28"), "price" : 67.84 }
{ "_id" : ObjectId("5b7d4aad8e6123a7a302be2b"), "price" : 157.68 }
{ "_id" : ObjectId("5b7d4a898e6123a7a302be29"), "price" : 289.78 }
查询后只显示price列,并且按照价格升序,类似select price from books order by price 
 
> db.books.find({},{"price":1}).sort({"price":-1})
与上面相反,按价格降序。
 
> db.books.find().count()
7
返回查询结果的总记录数。
 
> db.books.findOne()
查询第一条记录
3.4 修改和删除指令
> db.books.update({"name":"java"},{$set:{"name":"javase","price":50.01}})
把name为java的这条数据更新为name=javase和price=50.01。格式update({},{}),第一个{}为要更改的数据,第二个为要修改为什么数据。类似update books set name="javase" and price=50.01 where name="java"
注意,如果存在多个name为java的则只修改一个,下面看如何更新多个。之前我们存在名为spring的书籍有两本。现在把这两本价格都修改为50.
 
> db.books.update({"name":"spring"},{$set : {"price":50}},{multi:true})
> db.books.find()
{ "_id" : ObjectId("5b7d4a588e6123a7a302be25"), "name" : "spring", "price" : 50 }
{ "_id" : ObjectId("5b7d58deabdfa1fbe797fa0b"), "name" : "spring", "price" : 50 }
结果为name为spring的都修改了,{multi:true}表示是否修改多行,默认是为false。
 
> db.books.remove({"name":"spring"})
> db.books.find()
{ "_id" : ObjectId("5b7d4a6b8e6123a7a302be27"), "name" : "springMvc", "price" : 19.99 }
{ "_id" : ObjectId("5b7d4a898e6123a7a302be29"), "name" : "linux", "price" : 289.78 }
{ "_id" : ObjectId("5b7d4a9f8e6123a7a302be2a"), "name" : "python", "price" : 29.78 }
{ "_id" : ObjectId("5b7d4aad8e6123a7a302be2b"), "name" : "c++", "price" : 157.68 }
删除name为spring的书籍,默认是存在多少个就删除多少个,与update相反。
 
> db.books.remove({}) 删除当前集合的所有数据,不要乱用。
3.5 索引的操作指令
> db.books.ensureIndex({"name":1,"price":-1}) 
创建组合索引,mongodb会自动为索引创建名字,如果{}里面为一个,则为单个索引,多个就为组合索引,其中1和-1表示索引的方向。
 
> db.books.ensureIndex({"price":1},{"name":"index_price"})
创建一个索引,并指定索引的名字。
 
> db.books.ensureIndex({"name":1},{"unique":true})
为name创建一个唯一索引
 
> db.books.getIndexes()
查看当前集合中的索引信息。

> db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "test.student", "name" : "_id_" }
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "test.books", "name" : "_id_" }
{ "v" : 1, "key" : { "name" : 1, "price" : 1 }, "ns" : "test.books", "name" : "name_1_price_1" }
{ "v" : 1, "key" : { "price" : 1 }, "ns" : "test.books", "name" : "index_price" }
{ "v" : 1, "key" : { "name" : 1 }, "unique" : true, "ns" : "test.books", "name" : "name_1" }
索引的信息存在每个数据库的system.indexes集合里面,这里是查看所有的索引信息,需要与上面区别开。
 
> db.books.dropIndex("name_1")
{ "nIndexesWas" : 4, "ok" : 1 }
删除在books集合中索引名为name_1的索引
 
> db.books.dropIndexes()
{
        "nIndexesWas" : 3,
        "msg" : "non-_id indexes dropped for collection",
        "ok" : 1
}
删除在books集合中的所有索引。

db.collection.createIndex(keys, options)
语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。

在后台创建索引:db.values.createIndex({open: 1, close: 1}, {background: true})

转载文章
MongoDB 教程
MongoDB教程
MongoDB入门教程(1)

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

推荐阅读更多精彩内容