mongo更新数组字段_MongoDB 数组字段的查询和更新

标签:

MongoDB是文档型数据库,每个文档(doc)表示数据的一项记录。相比关系型DB的row只能使用简单的数据类型,doc能够使用复杂的数据类型:内嵌doc,数组。MongoDB的数组是一系列元素的集合,使用中括号 [] 表示数组,例如:[1,2,3]的元素是整数值,[{name:"t5"}, {name:"t7"}],[ {name:"t5", age:21}, {name:"t7", age:22} ]的元素是doc。

创建示例collection,使用db.collection.insert()函数和数组参数,一次性向集合中插入3个doc。

user1={ name:"t1", age:21}

user2={ name:"t2", age:22}

user3={ name:"t3", age:23}

db.users.insert([user1,user2,user3])

一,使用dot标记法(dot notation)访问数组元素

MongoDB使用 dot 访问数组的元素,或内嵌doc字段。

MongoDB uses the dot notation to access the elements of an array and to access the fields of an embedded document.

users={

name:"t1",

age:21,

address: {phone:123,email:"xxx@163.com"},

followers:[{name:"a"},{name:"b"},{name:"c"}]}

address 字段是内嵌文档,查找phone是123的doc

db.users.find({"addr.phone":123})

followers 字段是数组,查询followers中存在name=“b”的doc

db.users.find({"followers.name":"b"})

二,修改字段的值

在MongoDB中,修改操作主要使用两个修改器:$set 和 $inc,这两个修改器具有upsert特性:如果doc中存在相应的字段,那么修改该字段的值;如果doc中不存在相应的字段,那么在doc中创建新的字段。$inc用于整数型字段,增加或减少字段的值,$set用于任意数据类型,替换字段的值。

1,使用$set修改器,增加followers数组,使用empty filter:{},表示更新集合中的所有doc

db.users.updateMany(

{},

{$set:

{

followers:[ {name:"t5"},{name:"t7"} ]

}

}

)

20180110205836452528.jpg

2,使用$inc修改器,增加age字段的值,每个doc的age字段的都增加1

db.users.updateMany(

{},

{$inc:{age:1}}

)

20180110205836461318.jpg

3,$set 和 $inc的不同之处在于:$set是替换现有字段的值,而$inc是在现有字段值的基础上,增加或减少指定的数值

示例,使用$set修改age的值,更新结束后,每个doc的age字段都是1

db.users.updateMany(

{},

{$set:{age:1}}

)

三,修改数组字段

如果要向数组中增加或删除一个元素,$set和$inc 都不能很好的满足这种需求,MongoDB有专用的 Array Operator,用于修改数组字段。

1,使用$push向doc中增加数组,或插入新的元素

$push:如果doc中存在相应的数组字段,那么向数组的尾部插入一个元素;如果doc中不存在相应的数组字段,那么向doc中创建一个数组字段,并初始化。

示例,第一次调用$push,由于doc中不存在comments字段,因此MongoDB向doc中新建comments 数组字段,并初始化数组

db.users.updateMany(

{},

{$push:{comments:{msg:"c1"}}}

)

示例,后续再次调用$push,向已有的数组字段的尾部追加一个元素

db.users.updateMany(

{},

{$push:{comments:{msg:"c2"}}}

)

2,向数组字段插入多个元素

$push 修改器每次只能向数组字段的尾部插入一个元素,搭配使用$each 修改器,每次能向数组字段中插入多个元素

db.users.updateMany(

{},

{$push:

{

comments:{ $each:[ {msg:"c3"}, {msg:"c4"} ] }

}

}

)

3,从数组字段的特定位置处开始插入元素

使用$push 修改器只能将元素插入到数组字段的尾部,搭配使用$position 修改器,能够指定元素插入的开始位置,$position 必须和$each搭配使用。数组的下标是从0开始的。

db.users.updateMany

(

{},

{$push:

{comments:

{

$each:[ { msg:"c5"}, {msg:"c6"} ],

$position:2}

}

}

)

如果不使用$position 修改器,那么 $push 每次都向数组的末尾写入元素;使用$position 修改器,指定$push插入元素的开始位置。

$position :The $position modifier specifies the location in the array at which the $push operator insert elements. Without the $position modifier, the $push operator inserts elements to the end of the array.

4,限制数组中元素的数量

在$push 元素时,使用$slice=MaxNum限制数组元素的最大数量。只要没有达到最大数量,就会向数组中插入新的元素,直到达到最大值。$slice必须和$each搭配使用,如果数组字段的元素的数量已经达到最大值,根据MaxNum值的不同,会有不同的行为:

如果MaxNum=0,表示将数组清空;

如果MaxNum是正整数,表示数组只保留前面的MaxNum个元素;

如果MaxNum是负整数,表示数组只保留后面的MaxNum个元素;

示例,保留每个comments的最后5个元素

db.users.updateMany(

{},

{$push:

{comments:

{

$each:[ {msg:"c7"}, {msg:"c8"}, {msg:"c9"}],

$slice:-5}

}

}

)

5,对数组字段的元素进行排序

在限制数组字段的元素数量之前,使用$sort 操作符对元素进行排序,是数组元素有序排列。在$sort操作之后使用 $slice:MaxNum 修改器,由于数组元素是有序的,能够只保留序列前面或后面的特定数量的元素。

db.users.updateMany(

{},

{$push:

{comments:

{

$each:[ {msg:"c7"}, {msg:"c8"}, {msg:"c9"}],

$sort:{msg:1},

$slice:-5}

}

}

)

如果数组是[1,2,3]这种类型,那么$sort:1,按照1,2,3 升序排列; $sort:-1,安装3,2,1 降序排列。

6,使用$addToSet向数组插入无重复的元素

通过$push 插入元素,有可能插入重复的元素,MongoDB允许数组中的元素重复;如果一个数组不能插入重复值,可以使用$addToSet修改器, $addToSet在向数组插入元素时,首先检查元素是否已经存在于数组中,如果不存在,那么$addToSet将元素插入到数组中;如果存在,那么$addToSet不会插入任何元素。$addToSet只会保证不会插入重复的元素,不应影响数组中已经存在的重复元素。

$addToSet 能够一次性向数组中插入多个元素。

$addToSet only ensures that there are no duplicate items added to the set and does not affect existing duplicate elements. $addToSet does not guarantee a particular ordering of elements in the modified set.

示例,向comments 数组中插入三个messge

db.users.updateMany(

{},

{$addToSet:

{comments:[ {msg:"c7"}, {msg:"c8"}, {msg:"c9"}] }

}

)

7,使用$pop删除数组头部或尾部的元素

把数组看作是队列,下标为0的元素是在队列尾部,使用$pop删除元素时,{$pop:{array_name:N}} 表示从数组的末尾删除N个元素,{$pop:{array_name:-N}} 表示从数组的头部删除N个元素。

db.users.updateMany(

{},

{$pop:{comments:1}}

)

8,根据queyr filter删除数组元素

db.users.updateMany(

{},

{$pull:{comments:{msg:"c6"}}}

)

9,根据数组的下标修改元素,数组下标是从0开始的

对于js的数组 arr,包含两个element,修改第一个元素的like 字段,将其值设置为2.

var arr=[{name:"t1",like:1},{name:"t2",like:2}]arr[0].like=2

print(tojoson(arr))

在MongoDB中,如果要修改doc中的数组,可以使用 dot notation,使用 arrary.index.field 对数组中特定位置的元素进行修改。

db.users.updateMany(

{},

{$inc:{"comments.0.likes":1}}

)

如果不知道数组元素的下标,MongoDB提供占位符 $,用于匹配数组的第一个元素,对其进行更新。占位符 $ 表示第一个匹配的元素,格式是:arrary.$.field

$: Acts as a placeholder to update the first element that matches the query condition in an update.

db.users.update(

{},

{$inc:{"comments.$.likes":1}}

)

10,元素匹配符 $elemMatch

$elemMatch 是对数组元素的字段进行过滤,如果元素的字段满足查询条件,那么返回该元素所在的doc。

格式是:{arrar_name:{$elemMatch:{field_query_filter,,,,}}}

The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.

db.users.find({comments:{$elemMatch:{like:1}}})

11,数组元素的比较

如果有以下三个doc,每个doc中都有一个grades 数组:

{ "_id" : 1, "grades" : [ 80, 85, 90] }

{ "_id" : 2, "grades" : [ 88, 90, 92] }

{ "_id" : 3, "grades" : [ 85, 100, 90 ] }

示例1,对于query filter:{$gt:{grades:85}, $lt:{grades:100}},分析这3个数组是否满足:

第1个数组:元素 90 满足大于 85,所有的元素都小于100

第2个数组:所有的元素满足条件

第3个数组:元素90,100 满足大于85的条件,元素85,90满足小于100的条件

因此,只要数组中有任何一个元素满足qeury filter,就算满足qeury filter,这3个数组都满足query filter。

示例2,query filter:{grades:90}

只要数组中有一个元素的值是90,就满足query filter,因此,这3个数组都满足条件。

参考doc:

标签:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值