MongoDB是一个面向文档的数据库
文档主键
文档主键的唯一性
支持所有数据类型(数组除外)
复合主键
对象主键ObjectId
默认的文档主键
快速生成的12字节id
包含创建时间
mongo shell的使用
创建文档
db.collection.insertOne()
db.<collection>.insertOne(
<document>,
{
writeConcern:<document>
}
)
writeConcern 文档定义了本次文档创建操作的安全写级别,安全写级别判读一次数据库写入操作是否成功,安全级别越高,丢失风险就越低,写入操作延迟也可能更高
数组操作符
{<field>:{ $all:[<value1>,<value2>... ] } }
{<field>:{$elemMatch:{<query1>,<query2>,...} } }
筛选文档
{<field>:{:/pattern/,:'<option>'} }
{<field>:{:/pattern/<options>} }
在和$in操作符一起使用时,只能使用/pattern/<options>
读取用户姓名以c或j开头的银行文档对象
db.accounts.find( { name:{ $in : [ /^c/, /^j/ ] } } )
读取用户姓名包含LIE(不区分大小写)的银行文档
db.accounts.find ({ name : { $regex: /LIE/, $options: ' i ' } } )
文档游标
db.collection.find() 返回一个文档集合游标在不迭代游标的情况下,只列出前20个文档
使用游标下标访问集合中的某一文档
>var myCursor = db.accountd.find();
myCursor[0]
游标10分钟后会自动关闭
可以使用noCursorTimeout()函数来保持游标一直有效
>var myCursor = db.accounts.find().noCursorTimeout()
游标的主动关闭
>myCursor.close()
cursor.hasNext() 集合中还有未游历的文档,返回true
cursor.next() 游标指向下一个文档集的文档
>var myCursor = db.accounts.find({ name:"lihua" });
while(myCursor.hasNext()) {
printjson(myCursor.next())
}
cursor.forEach(<function>)
var myCursor = db.accounts.find({name: "lihua"});
myCursor.forEach(printjson)
cursor.limit(<number>)
cursor.skip(<offset>)
>db.accounts.find ({name:"lisi"}).limit(1)
count函数
cursor.count(<applySkipLimit>)
默认情况下,<applySkipLimit>为false,即cursor.count()不会考虑cursor.skip()和
cursor.limit()的效果
排序 1 正向排序 -1 逆向排序
cursor.sort(<docment>) document定义排序的要求
按照余额从大到小用户姓名按字母排序的方式排列银行账户文档
>db.accounts.find().sort({ balance: -1 ,name: 1} )
读取余额最大的银行账户文档
>db.accounts.find().sort({balance: -1} ) .limit(1)
cursor.skip()在cursor.limit()之前执行
cursor.sort()在cursor.skip()和cursor.limit()之前执行
sort->skip->limit
文档投影
db.collection.find(<query>,<projection>)
不使用投影时,db.collection.find()返回符合筛选条件的完整文档
使用投影可以有选择性的返回文档中的部分字段
{field:inclusion}
1表示返回字段,0表示不返回字段
>db.accounts.find( { }, {name:1} )
默认返回文档主键
>db.accounts,.find({ }, { name:1,_id:0 } )
除了文档主键之外,不可以在文档主键中混合使用包含,和不包含这两个投影操作要么在投影文档中列出所有应该包含的字段,要么列出所有不应该包含的字段
在数组字段上使用投影
$slice操作符可以返回数组字段中的部分元素
>db.account.find({ },{_id:0,name:1,contact:{$slide:1} } ) //contact数组中第一个元素
contact:{$slide:-1} //contact数组中倒数第一个元素
contact:{$slide:[1,2]}
elemMatch和$操作符可以返回数组字段中满足筛选条件的第一个元素
db.accounts.find({ },
contact:{ $elemMatch:{ $gt: "Ireland "}}
)
更新文档
db.collection.update()
db.<collection>.update(<query>,<update>,<options>)
如果<update>文档不包含任何更新的操作符,db.collection.update(),将会使用<update文档直接替换集合中符合,<query>文档中筛选的条件
将alice的账户余额改为200
>db.accounts.update({name:"alice"},{name:"alice",blance:200 } )
文档主键_id不可更改
在使用<update>文档替换整篇被更新文档时,只有第一篇符合<query>文档会被更新
查询账户余额在20到80之间的账户文档
>db.account.update ({ balance: { $gt:20 , $lt : 80 }} ,{name:"bill",blance:50,gender:"M" } )
更新特定字段
$set 更新或新增字段
$unset 删除字段
$rename 重命名字段
$inc 加减字段
$mul 相乘字段
$min 比较减少字段值
$max 比较增大字段值
更新操作符
{$set: {<field1>:<value1>,... } }
>db.accounts.update (
{name: "jack"},
{$set:
{
"contact.5": "new contact"
}
}
)
如果向现有数组字段范围以外的位置添加新值,数组字段的长度会扩大,未被赋值的数组成员设置null
{$unset : {<field1>:" ",...} }
删除字段
>db.accounts.update(
{ name : "jack"},
{$unset:
{
balance:""
}
}
)
$unset 命令中的赋值("")对操作结果无影响
$unset命令中的字段根本不存在,那么文档内容将保持不变
$unset数组中的某一个元素中时,数组的长度不会改变,值被重置
{$rename: {<field1>:<newName1>,<field2>:<newName2>, . . . } }
重命名字段
$rename命令要重命名的字段不存在,文档内容不会改变
如果新的字段名已经存在,那么原有的字段会被覆盖
$rename 命令中的旧字段和新字段都不可以指向数组元素
更新字段值
{$inc:{<field1>:<amount1>, . . . } } //加减字段
{$mul: {<field1>:<number1>, . . . } } //相乘
更新账户余额
>db.accounts.update (
{name:"david "},
{$inc:
{
balance:-0.5
}
}
)
$inc和$mul命令只能应用在数字字段上
如果被更新的字段不存在,$inc 会创建字段,并将字段值设为命令中的增减值,而$mul会创建字段,但会把字段值设为0
比较之后更新字段值
{$min:{<field1>:<value1>, . . . }}
{$max:{<field1>:<value1>, . . . }}
更新之前多了比较操作,返回较小或较大的字段
如果被更新的字段不存在,$min 和 $max 会创建字段,并将字段值设为命令中的更新值
如果被更新的字段类型和更新值类型不一致,$min和$max命令会按照BSON数据类型排序规则进行比较
数组更新操作符
$addToSet 向数组中添加元素
$pop 向数组中移除元素
$pull 向数组中有选择的移除元素
$pullAll
$push 向数组中添加元素
向李华的账户文档中添加联系方式
>db.accounts.update (
{name:"lihua" },
{$addToSet: { concat: "China"} }
)
如果要插入的值已经存在数组字段中,则$addToSet不会再添加重复的值
使用$addToSet插入数组和文档时,插入值中的字段顺序也和已有值重复的时候,才被算做重复值忽略
$addToSet会将数组插入被更新的数组字段中,成为内嵌数组
如果想要将多个元素之间添加到数组字段中,则需要使用$each操作符
>db.accounts.update(
{name: "lihua"},
{$addToSet:{contact:{ $each: ["contact1","contact2" ] } } }
)
从数组字段中删除元素
{$pop: {<field>: <-1 | 1>, . . . } }
从李华的账户文档中删除最后一个联系方式
>db.accounts.update(
{ name: "lihua"},
{$pop: {contact : 1}}
)
$pop 操作符只能应用在数组字段上
删除掉数组中最后一个元素后,会留下空数组
从数组字段中删除特定元素
{$pull : {<field1>: <value|condition>, . . . }}
{$pull all :{<field1>: [<value1>,<value2> . . . ], . . . } }
{$pullAll :{<field1>: [<value1>,<value2> ] } } <=> {$pull : {<field1>: {$in: [<value1>,<value2> ] } } }
如果要删除的元素是一个数组,数组元素的值和排列顺序都必须和被删除的数组
完全一样
$pullAll 命令之会删除字段和字段排列顺序都完全匹配的文档元素
$pull命令会删去包含指定的文档字段和字段值的文档元素,
字段排列顺序不需要完全匹配
向数组字段中添加字段
{$push : {<field>,<value1>, . . .}}
和$addToSet命令一样,如果$push 命令中指定的数组字段不存在,这个字段会被添加到原文档
更新数组中的特定元素
db.collection.update (
{<array>: <query selector>},
{<update operator>: {"<array>.$": value }}
)
$是数组中第一个符合筛选条件的数组元素的占位符
搭配更新操作符使用,可以对满足筛选条件的数组元素进行更新
查看李华的银行文档
>db.accounts.find (
{name: "lihua"},
{name: 1, newArray: 1 , _id:0 }
).pretty()
{
"name": "lihua",
"newArray":[
"push2",
"push1"
]
}
>db.accounts.update(
{name: "lihua",
newArray: "pos2"
},
{
$set:{
"newArray.$":"update"
}
}
)
更新数组中的所有元素
{<update operator>: {"<array>.$[ ]":value } }
$[ ] 指代元素的所有元素
>db.accounts.update (
{name: "lihua"},
{$set:{
"contact.0.$[ ]" : "111111111"
}}
)
更新文档
db.<collection>.update(<query>,<update>,<options>)
<option>提供了update命令的更多选择
updat对应一篇命令中使用筛选条件只对应一篇文档。默认情况下,即使筛选条件对应了多篇文档,update命令仍然只会更新一篇文档
{multi:<boolean> }
multi选项来更新多个符合筛选条件的文档
>db.accounts.update(
{ },
{ $set:{
currency: "USD"
}},
{multi:true}
)
MongoDB只能保证单个文档操作的原子性,不能保证多个文档操作的原子性
删除文档
db.collection.remove()
db.<collection>.remove(<query>,<options>)
删除余额为50的银行文档
db.collections.remove({balance: 50 })
remove命令会删除所有符合筛选条件的文档,如果只想删除满足筛选条件的第一篇文档,可以使用justOne选项
>db.accounts.remove(
{balance: {$lt: 100} },
{justOne: true }
)
删除集合
db.collection.drop()
db.<collection>.drop({writeConcern: <document> } )
如果集合中文档数量很多,使用remove命令删除所有文档的效率不高,这种情况下,更有效的方法
是drop命令,重新建立文档,重建索引