概述
Mongo是一个高性能,开源,无模式的文档型数据库,它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。Mongo使用C++开发,提供了以下功能:
- 面向集合的存储:适合存储对象及JSON形式的数据。 动态查询:Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
- 完整的索引支持:包括文档内嵌对象及数组。Mongo的查询优化器会分析查询表达式,并生成一个高效的查询计划。
- 查询监视:Mongo包含一个监视工具用于分析数据库操作的性能。
- 复制及自动故障转移:Mongo数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。
- 高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)。
- 自动分片以支持云级别的伸缩性:自动分片功能支持水平的数据库集群,可动态添加额外的机器。
与传统型的关系数据库相比,mongodb不支持事务和sql.
基本用法
- 下载:http://www.mongodb.org/downloads
- 安装(这里仅指window的安装): 将下载的文件解压到一个目录,找到bin目录下的mongod.exe,在命令行执行。这将会开启mongodb的数据库服务器,命令行中出现connections信息的时候说明启动成功。默认情况下,数据库监听本机的27017端口,等待客户端连接。
*注意:mongodb需要一个文件夹来存放它的文件,默认的位置是C:\data\db。如果要改变这个位置,可以在执行mongodb命令时通过--dbpath指定,例如C:\mongodb\bin\mongod.exe --dbpath d:\test\mongodb\data。 - 数据库服务器启动后,可以通过mongo命令连接到mongodb服务器。与数据库服务器对应,默认情况下,mongo命令连接本机的27017端口,如果需要更改,通过--port 和–host设置。连接时将默认连接到test数据库。
另外,mongo命令采用javascript语言环境,所有操作都通过标准javascript语句进行。所以如果你对javascript不熟,就应该先了解一下javascipt.
基本命令
- db
该命令将会显示当前连接的是哪个数据库; - show dbs
显示出所有的数据库列表; - use mydb
其中mydb是其中的一个数据库名,该命令是切换到mydb数据库; - show collections
显示出当前数据库中所有的集合(collections),除了用户自己建立的集合,数据库中都 有一个系统自带的system.indexes。在mongdb中,所有的文档都存放在集合中。一个集合是一组相关的文档的集合,这些文档共享一组索引。
Mongdb的增删改查操作
-
插入
- insert()方法
例如:db.testData.insert( {name:’name’,age:24})
其中{name:’name’,age:24}是一个json对象,也是mongdb中的一个文档 testData是collection的名字,该命令用于向数据库中插入数据。除了insert(),还可以通过update()和save()方法来插入数据。 - Update()方法
调用参数中拥有upsert =true属性的update方法,在查询不到相应的数据时,就会插入一条数据。 如:db.inventory.update( { type: "book",item : "journal" }, { $set : { qty: 10 } }, { upsert : true } )
结果:{ "_id" :ObjectId("51e8636953dbe31d5f34a38a"), "item" :"journal", "qty" : 10, "type" : "book"}
- Save()方法
如果参数对象中没有”id”属性,或者该”id”属性的值不存在collection中,将会插入一条数据。 例:db.inventory.save({ type: "book", item: "notebook", qty: 40 } )
结果:{"_id" : ObjectId("51e866e48737f72b32ae4fbc"),"type" : "book", "item" : "notebook","qty" : 40 }
- insert()方法
-
查询
- 查询出该集合下所有的数据
命令:db.inventory.find({} )
或db.inventory.find()
其中inventory是collection的名字,在find()后调用pretty()函数,即:db. inventory.find().pertty()
可以将获得的结果格式化。 - 根据特定条件查询数据
在collection下,通过find()方法,并向方法中传入参数 来进行查询。 例:db.testData.find({ x : 18 } )
结果:{ "_id": ObjectId("51a7dc7b2cacf40b79990bf7"), "x" : 18 }
例:db.records.find( {"user_id": { $lt: 42} }, { history: 0})
即:查询user_id小于42,并且返回结果中不包含字段”history”。”$lt”是查询操作符,详细见:http://docs.mongodb.org/manual/reference/operator/.
该查询语句中{history: 0}是查询规则,默认情况下,查询会返回所有的字段。为了限制向应用程序发送数据的数量,可以通过查询规则来返回一部分字段。0表示不包含该字段,1表示包含该字段。 - 指定and条件
db.inventory.find( { type: 'food',price: { $lt: 9.95 } } )
结果为type值为”food”并且price小于9.95的数据。 - 指定 or条件
db.inventory.find( { $or: [ { qty: { $gt: 100 }}, { price: { $lt: 9.95 } } ] } )
结果为qty的值大于100或者price的值小于9.95的数据。 - 同时指定and和or条件
db.inventory.find( { type: 'food', $or:[ { qty: { $gt: 100 } }, {price: { $lt: 9.95 } } ] } )
- 在子文档中查询
- 在子文档中准确匹配
db.inventory.find( { producer:{ company: 'ABC123', address: '123 Street' } } )
这条语句将会查询出inventory集合下所有数据中produce属性指定的子文档company=”ABC123”并且address = “123Street”的数据。
另外也可以通过:db.inventory.find( { 'producer.company':'ABC123' } )
这种方式来查询。 - 根据数组查询
- 精确匹配
例:db.inventory.find({ tags: [ 'fruit', 'food', 'citrus' ] } )
该语句会查询出所有数据中满足tags属性的值是一个数组,并且数组中刚好包含'fruit', 'food', and 'citrus'这三个元素,并且是这个顺序的数据。 - 匹配数组中指定的元素
这个查询可以满足精确匹配数组中某个指定的元素 例如:db.inventory.find( { 'tags.0' : 'fruit' } )
这个查询会得到所有数据中属性tags是一个数组,并且数组的第一个元素为’fruit’的数据。
- 精确匹配
- 子文档中的数组
- 利用数组的下标来匹配子文档中的一个字段 例如:
db.inventory.find({ 'memos.0.by': 'shipping' } )
该操作会得到所有数据中满足memos属性为一个数组,并且数组的第一个元素的by属性值为’ 'shipping'’的数据。 - 不使用数组下标来匹配子文档的字段
例:db.inventory.find({ 'memos.by': 'shipping' } )
该操作会得到所有数据中 满足memos属性为一个数组,并且数组中至少有一个元素的by属性值为’shippiing’的数据。 - 匹配多个字段 例:
db.inventory.find( { 'memos.memo': 'on time', 'memos.by': 'shipping' } )
或者b.inventory.find({ memos: { $elemMatch: { memo : 'on time', by: 'shipping' } } } )
该操作会得到所有数据中满足memos属性为一个数组,并且数组中至少有一个元素的memo属性值为’on time’并且by属性值为’shipping’的数据。
- 利用数组的下标来匹配子文档中的一个字段 例如:
- 在子文档中准确匹配
- 使用游标 在查询一个collection的时候会查出很多数据,这时mongodb会返回一个游标对象,通过游标来获得每条数据。
- 通过循环遍历游标
var c = db.testData.find() while ( c.hasNext() )printjson( c.next() )
其中printjson()函数是将数据格式化为json形式,利于查看。 或者通过forEach()方法来遍历游标,例如:var myCursor = db.inventory.find( { type: 'food' } ); myCursor.forEach(printjson);
- 通过数组遍历游标
var c =db.testData.find() printjson( c [ 4 ] )
- 通过循环遍历游标
- 分析查询性能
explain()这个方法允许你分析查询的性能,帮助你决定如何加索引。
这个方法是通过find()方法返回的游标调用,即db.inventory.find({ type: 'food' } ).explain()。
- 限制返回数据的条数
例如:db.testData.find().limit(3)
- 其他的
返回一条数据 如:db.testData.findOne()
- 查询出该集合下所有的数据
-
修改
在mongodb中修改数据有两种办法,分别是db.collection.update()
和db.collection.save()
。其中update()可以修改已经存在的数据或者多个满足查询条件的数据。Save()方法可以覆盖有相同’_id’的数据。- Update方法
方法的定义:db.collection.update( <query>, <update>, { upsert:<Boolean>, multi: <Boolean>, } )
这里重点说updsert和multi.其中updsert如果为true,表示如果没有查询满足条件 的数据,则创建一条新数据。
Updest的默认值为false.Multi如果为true,表示修改满足条件的多条数据,false表示只修改第一条满足条件的数据,默认值为false.
例如:一条存在的数据:{ "_id" : 11, "item" : "DivineComedy", "stock" : 2 }
修改操作:db.books.update({ item: "Divine Comedy" }, { $set: { price: 18 }, $inc: { stock: 5 } } )
更新的结果:{"_id" : 11, "item" : "Divine Comedy","price" : 18, "stock" : 7 }
- Save方法
通过向save()方法传入包含有已存在数据”id”的参数,达到覆盖已存在数据的目的。
方法的定义:db.collection.save(document)
如果document并没有包含’id’字段,这个save()方法就会执行插入操作。
例子: 已存在数据:{"_id" : 100, "item" : "water", "qty" :30 }
修改:db.products.save({ _id : 100, item : "juice" } )
结果:{"_id" : 100, "item" : "juice" }
- Update方法
-
删除
在mongodb中,db.collection.remove()方法用于删除collection中的数据。- 删除所有的数据
db.inventory.remove()
- 删除符合条件的数据
db.inventory.remove( { type :"food" } )
- 删除符合条件的一条数据
db.inventory.remove( { type : "food" }, 1 )
- 删除所有的数据
好了,先写这么多,mongodb的命令很多,我现在仅仅学习了很基本的增删改查命令,以后有时间接着写。中间有什么错误还希望大家多指正。