MongoDB进阶系列(11)——“改”的那些事(二)文档的keyvalue为数组的修改方法

本文将讨论关于文档中keyvalue为数组的情况如何修改数组。

首先,创建一个c4集合,集合中的文档包含一个arrint字段,值是一个整数数组;一个arrjson字段,值是一个Json对象数组。

> for(i=0;i<5;i++)
2015-03-12T22:06:52.051+0800 SyntaxError: Unexpected end of input
> for(i=0;i<5;i++){
... db.c4.insert({name:"row"+i,arrint:[i+1,i+2,i+3],arrjson:[{name:"j"+i,age:20+i}]})}
WriteResult({ "nInserted" : 1 })
> db.c4.find()
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
{ "_id" : ObjectId("55019e3555c37c4b941feb4c"), "name" : "row1", "arrint" : [ 2, 3, 4 ], "arrjson" : [ { "name" : "j1", "age" : 21 } ] }
{ "_id" : ObjectId("55019e3555c37c4b941feb4d"), "name" : "row2", "arrint" : [ 3, 4, 5 ], "arrjson" : [ { "name" : "j2", "age" : 22 } ] }
{ "_id" : ObjectId("55019e3555c37c4b941feb4e"), "name" : "row3", "arrint" : [ 4, 5, 6 ], "arrjson" : [ { "name" : "j3", "age" : 23 } ] }
{ "_id" : ObjectId("55019e3555c37c4b941feb4f"), "name" : "row4", "arrint" : [ 5, 6, 7 ], "arrjson" : [ { "name" : "j4", "age" : 24 } ] }
>

这里先对整数数组的进行讨论。

要为数组中增加一个整数元素,可以用$push方法。

取出一个数,可以用$pop,将数组字段设置为1则为最后一个元素,-1则为第一个元素

这里都是栈的形式,都是从数组末尾插入、取出,先进后出。

$push功能:

如果 filed 是一个已经存在的数组,那么把 value 追加给 field;

如果 field 原来不存在,那么新增 field 字段,把 value 的值赋给 field;

如果 field 存在,但是不是一个数组,将会出错;

$push一次只能压入一个值,如果你强行给其多个数,如[11,12]。那么MongoDB会将[11,12]认为是一个独立完整的元素,将[11,12]作为下一个元素整个插入到数组中。

> db.c4.update({name:"row0"},{$push:{arrint:10}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 10 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
> 
> db.c4.update({name:"row0"},{$push:{arrint:[11,12]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 10, [ 11, 12 ] ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
> 
> db.c4.update({name:"row0"},{$pop:{arrint:1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 10 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
> db.c4.update({name:"row0"},{$pop:{arrint:1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>

如果想压入多个数,需要用到$pushAll:[ ],这里的中括号其实是一个操作符,用来逐一操作多个数。

> db.c4.update({name:"row0"},{$pushAll:{arrint:[13,14]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 13, 14 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>


如果你像集合那样,希望加入的元素不要有重复,那么请用$addToSet。

功能:

如果 filed 是一个已经存在的数组,并且 value 不在其中,那么把 value 加入到数组;

如果 filed 不存在,那么把 value 当成一个数组形式赋给 field;

如果 field 是一个已经存在的非数组类型,那么将会报错;

> db.c4.update({name:"row0"},{$addToSet:{arrint:14}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.c4.update({name:"row0"},{$addToSet:{arrint:14}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.c4.update({name:"row0"},{$addToSet:{arrint:15}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 13, 14, 15 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>

相同地,如果要$addToSet多个值也是需要另辟蹊径的。需要与$each配合使用。

> db.c4.update({name:"row0"},{$addToSet:{arrint:{$each:[15,16]}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 13, 14, 15, 16 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>


$pull

语法:

{ $pull : { field : _value } }

功能:

如果 field 是一个数组,那么删除符合_value 检索条件的记录;

如果 field 是一个已经存在的非数组,那么会报错;


$pullAll

语法:

{ $pullAll : { field : value_array } }

功能:

同$push 类似,只是 value 的数据类型是一个数组


> db.c4.update({name:"row0"},{$pull:{arrint:16}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 13, 14, 15 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
> db.c4.update({name:"row0"},{$pull:{arrint:{$gte:15}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 13, 14 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
> 
> db.c4.update({name:"row0"},{$pullAll:{arrint:[13,14]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>



$rename

语法:

{ $rename : { old_field_name : new_field_name }

功能:

重命名指定的字段名称,从 1.7.2 版本后开始支持

> db.c4.update({name:"row0"},{$rename:{arrint:"arraryInt"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrjson" : [ { "name" : "j0", "age" : 20 } ], "arraryInt" : [ 1, 2, 3 ] }
>


下面我们进入本文的一个难点,对字段为Json对象数组的修改。

我们先对row0的文档的arrjson字段再添加几个json对象。

> db.c4.update({name:"row0"},{$pushAll:{arrjson:[{name:'j001',age:20},{name:'j0',age:30}]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrjson" : [ { "name" : "j0", "age" : 20 }, { "name" : "j001", "age" : 20 }, { "name" : "j0", "age" : 30 } ], "arraryInt" : [ 1, 2, 3 ] }
>

现在要将row0文档的arrjson字段数组中第一个name为“j0”的对象的age改为25。

> db.c4.update({name:"row0","arrjson.name":"j0"},{$set:{"arrjson.$.age":25}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrjson" : [ { "name" : "j0", "age" : 25 }, { "name" : "j001", "age" : 20 }, { "name" : "j0", "age" : 30 } ], "arraryInt" : [ 1, 2, 3 ] }
>

特殊操作符:$

$操作符代表查询记录中第一个匹配条件的记录项。

上例中,首先第一个{ }是筛选条件,其中"arrjson.name"选择出arrjson数组中所有name字段为'j0'的json对象。后一个{ }是修改方法,是再前面筛选出来的文档中进行修改,如果用$set:{"arrjson.age":25},无法确定那个子对象是刚才找到的name为'j0'的子对象,所以,这里需要用到$,表示刚才符合第一个匹配条件的那个对象下的age。


你可能感兴趣的:(mongodb)