MongoDB是一个基于文档的开源数据库,其摒弃了传统的对象关系模型(Object Relational Mapping)来提高开发效率。
在MongoDB中用文档(document)来表示一条记录,文档是一个类似JSON对象的数据结构,由域(field)和值(value)组成,其中值可以是简单数据类型,也可以是文档(document)或数组(array)。
MongoDB用集合(collections)存储文档(documets),类似于关系型数据库中的表格。和表格不同的是,一个集合允许其存储的文档具有不用的数据模型。
在MongoDB中,文档必须有且仅有一个充当主键作用的_id域。
导入数据库
下面的例子用到了learnMongo数据库中的users集合,这里是users集合中的一个样本文档:
{ "name": "xiaoming", "age": 22, "gender": "male", "grades": { "math": 80, "english": 70 } }
接着我们演示如何将users集合导入到learnMongo数据库中。
首先,启动mongod服务,MongoDB默认监听端口27017。
然后,从github上面git@github.com:zxiaocun/learnMongo.git取数据库文件。
git clone git@github.com:zxiaocun/learnMongo.git最后,打开命令行终端并切换至目录MongoDB\Server\3.0\bin,运行下面命令导入users集合到learnMongo数据库。如果users集合已经存在于learnMongo数据库中,该命令会先删除users集合,请注意users.json文件的存储路径。
mongoimport --db learnMongo --collection users --drop --file users.json
mongoimport默认连接到本地localhost的27017端口,我们可以使用--host和--port指定主机和端口。
插入数据
我们通过insert()方法向集合中添加文档,如果指定的集合不存在,MongoDB会自动创建该集合。首先,切换到LearnMogo数据库:
use learnMongo向users集合中添加一条记录,如果添加的文档没有包含域_id,MongoDB会自动为文档添加域_id,并生成一个ObjectId作为域_id的值:
db.users.insert({ "name" : "chenxiao", "age" : 18, "gender" : "female", "grade" : { "math" : 100, "english" : 100 } })该方法返回 WriteResult 对象,用于表示操作结果。.
WriteResult({ "nInserted" : 1 })
查找数据
你可以使用find()方法从集合中查找数据,find()方法可以返回集合中的全部文档或仅仅返回符合查询条件的文档。find()方法的返回结果是一个游标(cursor),你可以对返回结果进行遍历。查找users集合中的全部文档:
db.users.find()
可以通过给find()方法传入查询条件来查找指定的文档,查询条件通常有如下的形式:
{ <field1>: <value1>, <field2>: <value2>, ... }
如果域(field)是内嵌在文档或数组当中,你必须用点(.)运算符指定域,同时将整个域包含在引号当中。
下面查找名称是xiaoming的文档:
db.users.find( { "name": "xiaoming" } )
域grade的值是一个文档,文档里面包含了域math和english,如果我们想要查询math的值等于90的文档,我们可以使用点(.)运算符,如下所示:
db.users.find( { "grade.math": 80 } )
MongoDB提供了一系列运算符方便我们指定查询条件,例如比较运算符和条件运算符。下面我们分别查询math大于90和english小于95的文档:
db.users.find( { "grade.math": { $gt: 90 } } )
db.users.find( { "grade.english": { $lt: 95 } } )
我们查寻math和english都大于90的文档:
db.users.find( { "grade.math": {$gt:90}, "grade.english": {$gt:90} } )
你可以通过使用$or运算符指定逻辑或条件,我们查询math或english大于90的文档:
db.users.find(
{ $or: [ { "grade.math":{ $gt:90} }, { "grade.english": {$gt:90} } ] }
)
修改数据
- 查询条件(用于匹配需要修改的文档)
- 文档内容(用于指定修改后的文档内容)
- 可选参数
db.users.update( { "name" : "xiaoming" }, { $set: { "age": 25 } } )
db.users.update( { "name" : "xiaoming" }, { $set: { "grade.math": 100 } } )使用multi选项将所有年龄为25的同学的数序成绩改为100:
db.users.update( { "age": 25}, { $set: { "grade.math": 100 } }, { multi: true} )通过将整个文档作为第二个参数传入update(),我们可以替换掉除_id域之外的所有数据,域_id是不可以修改的,所以新的文档数据不必包含_id域,
db.users.update( { "name" : "xiaoming" }, { "name" : "xiaoming", "address" : { "province" : "henan", "city" : "luoyang" } } )
删除数据
db.users.remove( { "age": 25 } )默认情况,remove()会删除所有匹配的文档,我们可以使用justOne选项指定仅仅删除匹配的第一条数据,下面我们删除第一条math为100的数据:
db.users.remove( { "grade.math": 100 }, { justOne: true } )如果要删除数组中的所有文档,传递一个空的查询条件{}到remove()方法,下面删除users集合中的所有数据:
db.users.remove( { } )我们可以使用drop()删除指定的集合,下面我们删除users集合:
db.users.drop()
数据聚合
db.users.aggregate( [ { $group: { "_id": "$age", "count": { $sum: 1 } } } ] );我们可以在分组和计算之前执行查询操作,下例我们统计数学成绩大于80的每个年龄的学生人数:
db.users.aggregate( [ { $match: { "grade.math": {$gt:80}} }, { $group: { "_id": "$age" , "count": { $sum: 1 } } } ] );
数据索引
db.users.createIndex( { "name": 1 } )我们可以同时创建多个索引,下面我们为users集合的name创建一个升序的索引,为age创建一个降序的索引:
db.users.createIndex( { "name": 1, "age": -1 } )