一、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})