Open libin1991 opened 6 years ago
MongoDB是一个基于分布式文件存储的开源数据库系统。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
brew install mongodb
data
mkdir data
mongod --dbpath='./data'
如果出现waiting for connections on port 27017就表示启动成功。
waiting for connections on port 27017
注意:这个命令窗体绝对不能关,关闭这个窗口就相当于停止了mongodb服务
mongod
mongo
也可以设置host
mongo --host 127.0.0.1
数据库
集合
文档
对应关系如下图:
show dbs
返回如下:
admin 0.000GB book 0.000GB leave 0.000GB local 0.000GB page 0.000GB school 0.000GB students 0.000GB
实例 切换到 school数据库下:
use school
switched to db school
注:如果此数据库存在,则切换到此数据库下,如果此数据库还不存在也可以切过来
注: 我们刚创建的数据库school如果不在列表内,要显示它,我们需要向school数据库插入一些数据
db.school.insert({name:'为民小学',age:10});
db 或 db.getName()
db.dropDatabase()
{ "dropped" : "school", "ok" : 1 }
db.school.help()
BCollection help db.school.find().help() - show DBCursor help db.school.bulkWrite( operations, <optional params> ) - bulk execute write ...
show collections
grade1 grade2
db.createCollection(collection_Name)
db.createCollection('grade3')
{ "ok" : 1 }
db.collection_Name.insert(document)
db.grade1.insert({name: 'Lily', age: 8})
WriteResult({ "nInserted" : 1 })
insert
db.collection_name.insert(document)
db.grade1.insert({name: 'Tom', age: 9})
note:每当插入一条新文档的时候mongodb会自动为此文档生成一个_id属性,_id一定是唯一的,用来唯一标识一个文档 _id也可以直接指定,但如果数据库中此集合下已经有此_id的话插入会失败。
{ "_id" : ObjectId("5addbfbb163098017a6a72ed"), "name" : "Tom", "age" : 9.0 }
save
db.collection_name.save(document)
note:如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。
// insert db.grade1.insert({_id: '1',name: 'Han Meimei', age: 8})// WriteResult({ "nInserted" : 1 }) // 存在{_id:1},则更新 _id为1的document db.grade1.save({_id: '1',name: 'Han Meimei', age: 9})// WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) // 不存在{_id:2},则插入一条新文档 db.grade1.save({_id: '2',name: 'Han Meimei', age: 9})// WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "2" })
执行脚本插入
mongo exc_js/1.js
db.collection.update( <query>, <updateObj>, { upsert: <boolean>, multi: <boolean> } )
query
update
$set
$inc
upsert
multi
{ $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } }
// 给 {name: 'Tom'} 的文档的age累加 10 db.grade1.update({name: 'Tom'}, {$inc: {age:10}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
$push
{ $push: { <field1>: <value1>, ... } }
db.grade1.update({name:'Tom'}, {$push: {'hobby':'reading'} }) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) // { "_id" : ObjectId("5addbfbb163098017a6a72ed"), "name" : "Tom", "hobby" : [ "reading" ] } // 不会覆盖已有的 db.grade1.update({name:'Tom'}, {$push: {'hobby':'reading'} }) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) // { "_id" : ObjectId("5addbfbb163098017a6a72ed"), "name" : "Tom", "hobby" : [ "reading", "reading" ] }
$addToSet
{ $addToSet: { <field1>: <value1>, ... } }
// /第一次没有 huge db.grade1.update({_id:3}, {$addToSet: {friends:'huge'}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) // 第二次 有 huge db.grade1.update({_id:3}, {$addToSet: {friends:'huge'}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
$pop
{ $pop: { <field>: <-1 | 1>, ... } }
1
-1
db.grade1.update({_id:3}, {$pop:{friends: 1}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) db.grade1.update({_id:3}, {$pop:{friends: -1}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
$each
{ $addToSet: { <field>: { $each: [ <value1>, <value2> ... ] } } }
db.grade1.update({_id:3}, {$addToSet:{friends:{$each: ['huangbo','zhangyixing']}}}) //WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) // 已经有的时候就不会再添加了 db.grade1.update({_id:3}, {$addToSet:{friends:{$each: ['huangbo','zhangyixing']}}}) //WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
{ $push: { <field>: { $each: [ <value1>, <value2> ... ] } } }
db.grade1.update({_id:3}, {$push:{friends:{$each: ['huangbo','zhangyixing']}}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
在$addToSet中使用时,若有则忽略,若没有则添加。在$push中使用时,不管有没有都会添加。
$ne
{field: {$ne: value} }
// 给 name为'Han Meimei' && hobby中不等于'reading' && _id不等于'2'的文档 的hobby 属性 添加一个 'drinking' db.grade1.update({name: 'Han Meimei', hobby:{$ne:'reading'}, _id: {$ne:'2'}}, {$push: {hobby: 'drinking'}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
{ $set: { <field1>: <value1>, ... } }
/* 原来的数据: {_id:3, info:{id: '11'}, friends:['liudehua', 'zhourunfa']} */ /*设置字段的第一层的值(Set Top-Level Fields)*/ db.grade1.update({_id:3}, {$set:{"info11":{id:'11'}}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) /*设置嵌套字段的值 (Set Fields in Embedded Documents)*/ db.grade1.update({_id:3}, {$set:{"info.id":'22'}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) /*修改指定索引元素*/ db.grade1.update({_id:3}, {$set:{"friends.1":'zhangmanyu'}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
$unset
{ $unset: { <field1>: "", ... } }
// 把 {name: 'Tom'} 的文档中的 age 键给删除掉 db.grade1.update({name: 'Tom'}, {$unset:{'age':''}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) /* { "_id" : ObjectId("5addbfbb163098017a6a72ed"), "name" : "Tom" }*/
语法
db.collection.remove( <query>, { justOne: <boolean> } )
参数说明
query :(可选)删除的文档的条件。 justOne : (可选)如果设为 true 或 1,则只删除匹配到的多个文档中的第一个。默认为 true
/*{justOne:true} 值删除匹配到的第一条文档*/ db.grade1.remove({'name': 'Han Meimei'}, {justOne: true}) // WriteResult({ "nRemoved" : 1 }) /*删除匹配到的所有文档*/ db.grade1.remove({'name': 'Han Meimei'}) // WriteResult({ "nRemoved" : 2 })
db.collection_name.find(query, projection);
参数
query - 使用查询操作符指定选择过滤器 projection - 指定配到到的文档中的返回的字段。
/*projection*/ { field1: <value>, field2: <value> ... } /*value:*/ 1 or true: 在返回的文档中包含这个字段 0 or false:在返回的文档中排除这个字段
note: _id字段默认一直返回,除非手动将_id字段设置为0或false
_id
0
false
举个栗子
//查询grade1下所有的文档 db.grade1.find()
$in
//原始数据(): { "_id" : 1, "name" : "Tom1", "age" : 9 } { "_id" : 2, "name" : "Tom2", "age" : 15 } { "_id" : 3, "name" : "Tom3", "age" : 11 }
db.grade1.find({age:{$in:[9,11]}}) // { "_id" : 1, "name" : "Tom1", "age" : 9 } // { "_id" : 3, "name" : "Tom3", "age" : 11 }
$nin
db.grade1.find({age:{$nin:[9,11]}}) // { "_id" : 2, "name" : "Tom2", "age" : 15 }
$not
db.grade1.find({age:{$not:{$lt:11}}}) //{ "_id" : 2, "name" : "Tom2", "age" : 15 } //{ "_id" : 3, "name" : "Tom3", "age" : 11 }
$gt
$gte
$lt
$lte
db.grade1.find({age:{$ne:9}}) // { "_id" : 2, "name" : "Tom2", "age" : 15 } // { "_id" : 3, "name" : "Tom3", "age" : 11 }
// 原始数据 { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }
db.grade1.find({"friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ]}) // { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } db.grade1.find({"friends" : [ "Lily" ]}) // 空 // $all db.grade1.find({"friends" :{$all: ["Zhang San"]}}) // { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } // $in db.grade1.find({"friends" :{$in: ["Zhang San"]}}) { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } // $size db.grade1.find({"friends" :{$size:4}}) //{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } // $slice db.collection.find( { field: value }, { array: {$slice: count } } ); > db.grade1.find({"friends" :{$size:4}}, {"friends":{$slice:2}}) //{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs" ] }
$where
$where可以接收两种参数传递给查询系统,一种是包含JavaScript表达式的字符串,另外一种是JavaScript函数。
$where非常灵活,但是它需要数据库集合中的每一个文档中处理这个JavaScript表达式或者JavaScript函数,所以会比较慢。
在JavaScript表达式或者JavaScript函数中引用文档的时候,可是使用this或者obj。
this
obj
// 数据库数据 { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] } // JS表达式的字符串 > db.grade1.find({$where:'this.name == "Tom1"'}) //{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } // 函数 > db.grade1.find({$where: function(){return this.age == 9}}) // { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] }
这些方法改变了执行基础查询方式。
包括cursor.forEach()、cursor.map()、cursor.limit()、cursor.size()、cursor.count()等。
cursor.forEach()
cursor.map()
cursor.limit()
cursor.size()
cursor.count()
// forEach举例 > var result = db.grade1.find({$where: function(){return this.age >= 9}}); > result.forEach(elem => printjson(elem)) /*{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }*/
// 大于等于 db.grade1.find({age:{$gte:9}}) /*{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }*/ // 大于等于9 并且 小于等于13 db.grade1.find({age:{$gte:9}, age: {$lte:13}}) /*{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }*/
//原始数据 { "_id" : ObjectId("5ae1b6e3e4366d57f3307239"), "name" : "Tom4" } > db.grade1.find({_id: '5ae1b6e3e4366d57f3307239'}).count() // 0 > db.grade1.find({_id:ObjectId('5ae1b6e3e4366d57f3307239')}).count() // 1
count() 查询结果的条数
count()
db.collection.find({key:/value/})
// name是以`T`开头的数据 db.grade1.find({name: /^T/}) /*{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] } { "_id" : ObjectId("5ae1b6e3e4366d57f3307239"), "name" : "Tom4" }*/
db.collection_name.find({field1: value1, field2:value2})
//原始数据 { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }
// and name是以‘T’开头 并且 age是9 的数据 > db.grade1.find({name: /^T/, age: 9}) // { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] }
db.collection_name.find({ $or: [{key1: value1}, {key2:value2} ] })
// name 是Tom1 或者 age是11 的数据 > db.grade1.find({$or:[{name: 'Tom1'}, {age: 11}]}) /*{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }*/
> db.grade1.find({age: 9,$or:[{name: 'Tom1'}, {age: 11}]}) /*{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] }*/
limit
db.collectoin_name.find().limit(number)
skip
db.collectoin_name.find().skip(number)
sort
-通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1为升序排列,而-1是用于降序排列。
db.collectoin_name.find().sort({field:1})
db.collectoin_name.find().sort({field:-1})
// 原始数据为 1 2 3 4 5 6 7 8 9 > var pageIndex = 3; > var pageSize = 3; > var res = db.grade1.find({}).skip((pageIndex - 1) * pageSize).limit(pageSize).sort({username: 1}); > res /*{ "_id" : ObjectId("5ae1cbc609f3ac9a41442546"), "username" : "Lily_7", "password" : 7 } { "_id" : ObjectId("5ae1cbc609f3ac9a41442547"), "username" : "Lily_8", "password" : 8 } { "_id" : ObjectId("5ae1cbc609f3ac9a41442548"), "username" : "Lily_9", "password" : 9 }*/ var res1 = db.grade1.find().skip((pageIndex - 1) * pageSize).limit(pageSize).sort({username: -1}); /*{ "_id" : ObjectId("5ae1cbc609f3ac9a41442542"), "username" : "Lily_3", "password" : 3 } { "_id" : ObjectId("5ae1cbc609f3ac9a41442541"), "username" : "Lily_2", "password" : 2 } { "_id" : ObjectId("5ae1cbc609f3ac9a41442540"), "username" : "Lily_1", "password" : 1 }*/
note: 没有先后顺序
之前我们使用MySQL等关系型数据库时,主键都是设置成自增的。但在分布式环境下,这种方法就不可行了,会产生冲突。为此,MongoDB采用了一个称之为ObjectId的类型来做主键。ObjectId是一个12字节的 BSON 类型字符串。按照字节顺序,一次代表:
1 前言
MongoDB是一个基于分布式文件存储的开源数据库系统。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
2 安装(mac)
3 mongodb启动与连接(mac)
3.1 服务端启动
3.1.1 启动步骤
data
)mongod --dbpath='./data'
如果出现
waiting for connections on port 27017
就表示启动成功。3.1.2
mongod
启动命令mongod参数说明3.2 客户端启动
也可以设置host
4 MongoDB基本概念
数据库
MongoDB的单个实例可以容纳多个独立的数据库,比如一个学生管理系统就可以对应一个数据库实例。集合
数据库是由集合组成的,一个集合用来表示一个实体,如学生集合。文档
集合是由文档组成的,一个文档表示一条记录,比如一位同学张三就是一个文档对应关系如下图:
5 数据库操作
5.1 查看所有数据库
返回如下:
admin 0.000GB book 0.000GB leave 0.000GB local 0.000GB page 0.000GB school 0.000GB students 0.000GB
5.2 使用数据库
实例 切换到 school数据库下:
返回如下:
db.school.insert({name:'为民小学',age:10});
5.3 查看当前使用的数据库
5.4 删除数据库
返回如下:
{ "dropped" : "school", "ok" : 1 }
6 集合操作
6.1 查看集合帮助
返回如下:
BCollection help db.school.find().help() - show DBCursor help db.school.bulkWrite( operations, <optional params> ) - bulk execute write ...
6.2 查看数据库下的集合
返回如下:
6.3 创建集合
db.createCollection(collection_Name)
)db.createCollection('grade3')
返回如下:
{ "ok" : 1 }
db.collection_Name.insert(document)
)db.grade1.insert({name: 'Lily', age: 8})
返回如下:
WriteResult({ "nInserted" : 1 })
7 文档操作
7.1 插入文档
insert
db.collection_name.insert(document)
db.grade1.insert({name: 'Tom', age: 9})
{ "_id" : ObjectId("5addbfbb163098017a6a72ed"), "name" : "Tom", "age" : 9.0 }
save
db.collection_name.save(document)
// insert db.grade1.insert({_id: '1',name: 'Han Meimei', age: 8})// WriteResult({ "nInserted" : 1 }) // 存在{_id:1},则更新 _id为1的document db.grade1.save({_id: '1',name: 'Han Meimei', age: 9})// WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) // 不存在{_id:2},则插入一条新文档 db.grade1.save({_id: '2',name: 'Han Meimei', age: 9})// WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "2" })
7.2 更新文档
7.2.1 语法 & 参数说明
query
查询条件,指定要更新符合哪些条件的文档update
更新后的对象或指定一些更新的操作符$set
直接指定更新后的值$inc
在原基础上累加upsert
可选,这个参数的意思是,如果不存在符合条件的记录时是否插入updateObj. 默认是false,不插入。multi
可选,mongodb 默认只更新找到的第一条记录,如果这个参数为true,就更新所有符合条件的记录。7.2.2 操作符
(1)
$inc
// 给 {name: 'Tom'} 的文档的age累加 10 db.grade1.update({name: 'Tom'}, {$inc: {age:10}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
(2)
$push
db.grade1.update({name:'Tom'}, {$push: {'hobby':'reading'} }) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) // { "_id" : ObjectId("5addbfbb163098017a6a72ed"), "name" : "Tom", "hobby" : [ "reading" ] } // 不会覆盖已有的 db.grade1.update({name:'Tom'}, {$push: {'hobby':'reading'} }) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) // { "_id" : ObjectId("5addbfbb163098017a6a72ed"), "name" : "Tom", "hobby" : [ "reading", "reading" ] }
(3)
$addToSet
// /第一次没有 huge db.grade1.update({_id:3}, {$addToSet: {friends:'huge'}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) // 第二次 有 huge db.grade1.update({_id:3}, {$addToSet: {friends:'huge'}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
(4)
$pop
1
删除最后一个元素-1
删除第一个元素db.grade1.update({_id:3}, {$pop:{friends: 1}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) db.grade1.update({_id:3}, {$pop:{friends: -1}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
(5)
$each
db.grade1.update({_id:3}, {$addToSet:{friends:{$each: ['huangbo','zhangyixing']}}}) //WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) // 已经有的时候就不会再添加了 db.grade1.update({_id:3}, {$addToSet:{friends:{$each: ['huangbo','zhangyixing']}}}) //WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
db.grade1.update({_id:3}, {$push:{friends:{$each: ['huangbo','zhangyixing']}}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
(6)
$ne
// 给 name为'Han Meimei' && hobby中不等于'reading' && _id不等于'2'的文档 的hobby 属性 添加一个 'drinking' db.grade1.update({name: 'Han Meimei', hobby:{$ne:'reading'}, _id: {$ne:'2'}}, {$push: {hobby: 'drinking'}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
(7)$set
/* 原来的数据: {_id:3, info:{id: '11'}, friends:['liudehua', 'zhourunfa']} */ /*设置字段的第一层的值(Set Top-Level Fields)*/ db.grade1.update({_id:3}, {$set:{"info11":{id:'11'}}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) /*设置嵌套字段的值 (Set Fields in Embedded Documents)*/ db.grade1.update({_id:3}, {$set:{"info.id":'22'}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) /*修改指定索引元素*/ db.grade1.update({_id:3}, {$set:{"friends.1":'zhangmanyu'}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
(8)
$unset
// 把 {name: 'Tom'} 的文档中的 age 键给删除掉 db.grade1.update({name: 'Tom'}, {$unset:{'age':''}}) // WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) /* { "_id" : ObjectId("5addbfbb163098017a6a72ed"), "name" : "Tom" }*/
7.3 删除文档
query :(可选)删除的文档的条件。 justOne : (可选)如果设为 true 或 1,则只删除匹配到的多个文档中的第一个。默认为 true
/*{justOne:true} 值删除匹配到的第一条文档*/ db.grade1.remove({'name': 'Han Meimei'}, {justOne: true}) // WriteResult({ "nRemoved" : 1 }) /*删除匹配到的所有文档*/ db.grade1.remove({'name': 'Han Meimei'}) // WriteResult({ "nRemoved" : 2 })
7.4 查询文档
7.4.1
/*projection*/ { field1: <value>, field2: <value> ... } /*value:*/ 1 or true: 在返回的文档中包含这个字段 0 or false:在返回的文档中排除这个字段
//查询grade1下所有的文档 db.grade1.find()
7.4.2 findOne()
7.4.3 查询操作符
(1)
$in
//原始数据(): { "_id" : 1, "name" : "Tom1", "age" : 9 } { "_id" : 2, "name" : "Tom2", "age" : 15 } { "_id" : 3, "name" : "Tom3", "age" : 11 }
db.grade1.find({age:{$in:[9,11]}}) // { "_id" : 1, "name" : "Tom1", "age" : 9 } // { "_id" : 3, "name" : "Tom3", "age" : 11 }
(2)
$nin
db.grade1.find({age:{$nin:[9,11]}}) // { "_id" : 2, "name" : "Tom2", "age" : 15 }
(3)
$not
db.grade1.find({age:{$not:{$lt:11}}}) //{ "_id" : 2, "name" : "Tom2", "age" : 15 } //{ "_id" : 3, "name" : "Tom3", "age" : 11 }
(4)
$gt
(5)
$gte
(6)
$lt
(7)
$lte
(8)
$ne
db.grade1.find({age:{$ne:9}}) // { "_id" : 2, "name" : "Tom2", "age" : 15 } // { "_id" : 3, "name" : "Tom3", "age" : 11 }
7.4.4 数组的用法
// 原始数据 { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }
db.grade1.find({"friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ]}) // { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } db.grade1.find({"friends" : [ "Lily" ]}) // 空 // $all db.grade1.find({"friends" :{$all: ["Zhang San"]}}) // { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } // $in db.grade1.find({"friends" :{$in: ["Zhang San"]}}) { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } // $size db.grade1.find({"friends" :{$size:4}}) //{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } // $slice db.collection.find( { field: value }, { array: {$slice: count } } ); > db.grade1.find({"friends" :{$size:4}}, {"friends":{$slice:2}}) //{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs" ] }
7.4.5
$where
$where
可以接收两种参数传递给查询系统,一种是包含JavaScript表达式的字符串,另外一种是JavaScript函数。$where
非常灵活,但是它需要数据库集合中的每一个文档中处理这个JavaScript表达式或者JavaScript函数,所以会比较慢。在JavaScript表达式或者JavaScript函数中引用文档的时候,可是使用
this
或者obj
。// 数据库数据 { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] } // JS表达式的字符串 > db.grade1.find({$where:'this.name == "Tom1"'}) //{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } // 函数 > db.grade1.find({$where: function(){return this.age == 9}}) // { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] }
7.4.6 Cursor Methods
这些方法改变了执行基础查询方式。
包括
cursor.forEach()
、cursor.map()
、cursor.limit()
、cursor.size()
、cursor.count()
等。// forEach举例 > var result = db.grade1.find({$where: function(){return this.age >= 9}}); > result.forEach(elem => printjson(elem)) /*{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }*/
8 条件操作符
8.1 条件操作符
$gt
- 大于$gte
- 大于等于$lt
- 小于$lte
- 小于等于// 大于等于 db.grade1.find({age:{$gte:9}}) /*{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }*/ // 大于等于9 并且 小于等于13 db.grade1.find({age:{$gte:9}, age: {$lte:13}}) /*{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }*/
8.2 使用_id进行查询
//原始数据 { "_id" : ObjectId("5ae1b6e3e4366d57f3307239"), "name" : "Tom4" } > db.grade1.find({_id: '5ae1b6e3e4366d57f3307239'}).count() // 0 > db.grade1.find({_id:ObjectId('5ae1b6e3e4366d57f3307239')}).count() // 1
8.3 正则匹配
// name是以`T`开头的数据 db.grade1.find({name: /^T/}) /*{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] } { "_id" : ObjectId("5ae1b6e3e4366d57f3307239"), "name" : "Tom4" }*/
9 与和或
9.1 and
//原始数据 { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 2, "name" : "Tom2", "age" : 15, "friends" : [ "Zhange San", "Li Si" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }
// and name是以‘T’开头 并且 age是9 的数据 > db.grade1.find({name: /^T/, age: 9}) // { "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] }
9.2 or
// name 是Tom1 或者 age是11 的数据 > db.grade1.find({$or:[{name: 'Tom1'}, {age: 11}]}) /*{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] } { "_id" : 3, "name" : "Tom3", "age" : 11, "friends" : [ "Zhange San", "Lily" ] }*/
9.3 and 和 all 联合使用
> db.grade1.find({age: 9,$or:[{name: 'Tom1'}, {age: 11}]}) /*{ "_id" : 1, "name" : "Tom1", "age" : 9, "friends" : [ "Lily", "Jobs", "Lucy", "Zhang San" ] }*/
10 分页查询
10.1
limit
10.2
skip
10.3
sort
-通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1为升序排列,而-1是用于降序排列。
10.4 分页
// 原始数据为 1 2 3 4 5 6 7 8 9 > var pageIndex = 3; > var pageSize = 3; > var res = db.grade1.find({}).skip((pageIndex - 1) * pageSize).limit(pageSize).sort({username: 1}); > res /*{ "_id" : ObjectId("5ae1cbc609f3ac9a41442546"), "username" : "Lily_7", "password" : 7 } { "_id" : ObjectId("5ae1cbc609f3ac9a41442547"), "username" : "Lily_8", "password" : 8 } { "_id" : ObjectId("5ae1cbc609f3ac9a41442548"), "username" : "Lily_9", "password" : 9 }*/ var res1 = db.grade1.find().skip((pageIndex - 1) * pageSize).limit(pageSize).sort({username: -1}); /*{ "_id" : ObjectId("5ae1cbc609f3ac9a41442542"), "username" : "Lily_3", "password" : 3 } { "_id" : ObjectId("5ae1cbc609f3ac9a41442541"), "username" : "Lily_2", "password" : 2 } { "_id" : ObjectId("5ae1cbc609f3ac9a41442540"), "username" : "Lily_1", "password" : 1 }*/
11 ObjectId构成
之前我们使用MySQL等关系型数据库时,主键都是设置成自增的。但在分布式环境下,这种方法就不可行了,会产生冲突。为此,MongoDB采用了一个称之为ObjectId的类型来做主键。ObjectId是一个12字节的 BSON 类型字符串。按照字节顺序,一次代表:
12 参考