《MongoDB》 数组操作_mongodb数组-程序员宅基地

技术标签: 数据库  mongodb  

1.数组末尾加入一个元素

push的作用就是,如果指定的键已经存在,它会向已有的数组末尾加入一个元素,要是没有就会创建一个新的数组

db.user.update({
    “_id” : ObjectId(4ffcb2ed65282ea95f7e3304”)},{
    $push:{
    “relationships”:{
    “fname”:”xiong”,”lname”:”lan”}}})
"_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),

"age" : 23,

"favorite" : {
    

    "1" : "reading",

    "2" : "swimming",

    "3" : "listening music"

},

"fname" : "jeff",

"height" : 166,

"lname" : "jiang",

"relationships" : [

    {
    

        "fname" : "deng",

        "lname" : "pan"

    },

    {
    

        "fname" : "qiang",

        "lname" : "he"

    },

    {
    

        "fname" : "dongren",

        "lname" : "zeng"

    },

    {
    

        "fname" : "xiong",

        "lname" : "lan"

    }

]

2.数组末尾删除一个元素

对数组进行“减”操作,能达到对数组“减”目的的修改器有两个,pop和pull

db.user.update({
    “_id” : ObjectId(4ffcb2ed65282ea95f7e3304”)},{
    $pop:{
    “relationships”:1}})
"_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),

"age" : 23,

"favorite" : {
    

    "1" : "reading",

    "2" : "swimming",

    "3" : "listening music"

},

"fname" : "jeff",

"height" : 166,

"lname" : "jiang",

"relationships" : [

    {
    

        "fname" : "deng",

        "lname" : "pan"

    },

    {
    

        "fname" : "qiang",

        "lname" : "he"

    },

    {
    

        "fname" : "dongren",

        "lname" : "zeng"

    },

]

3.数组开头删除一个元素

从数组的开头删除该怎么办呢。很简单,把上面的“1”改成“-1”,它将逆向操作

db.user.update({
    “_id” : ObjectId(4ffcb2ed65282ea95f7e3304”)},{
    $pop:{
    “relationships”:-1}})
"_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),

"age" : 23,

"favorite" : {
    

    "1" : "reading",

    "2" : "swimming",

    "3" : "listening music"

},

"fname" : "jeff",

"height" : 166,

"lname" : "jiang",

"relationships" : [


    {
    

        "fname" : "qiang",

        "lname" : "he"

    },

    {
    

        "fname" : "dongren",

        "lname" : "zeng"

    }

]

4.数组中间删除一个元素

想删除数组中间的呢。这时,$pull派上用场
pull可以将数组中间的数据删除。这里还有一点要注意,pull会将所有匹配到的数据都删除

db.user.update({
    “_id” : ObjectId(4ffcb2ed65282ea95f7e3304”)},{
    $pull:{
    “relationships”:{
    “fname”:”dongren”,”lname”:”zeng”}}})
"_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),

"age" : 23,

"favorite" : {
    

    "1" : "reading",

    "2" : "swimming",

    "3" : "listening music"

},

"fname" : "jeff",

"height" : 166,

"lname" : "jiang",

"relationships" : [

    {
    

        "fname" : "qiang",

        "lname" : "he"

    },

    {
    

        "fname" : "xiong",

        "lname" : "lan"

    }

]

5.过滤元素

1.我们再往数组里插入一相同的数据,它是能正常插入到数组的。而在实际生产环境中,我们都不想看到这样的结果,
那么,这里又出现了两个可以用的修改器:ne和addToSet。$ne主要拿来判断,若数组里面有这个值,则不插入;没有才插入

db.user.update({
    “relationships.fname”:{
    ne:"xiong"}},{
    set:{
    “fname”:”xiong”,”lname”:”lan”}})
"_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),

"age" : 23,

"favorite" : {
    

    "1" : "reading",

    "2" : "swimming",

    "3" : "listening music"

},

"fname" : "jeff",

"height" : 166,

"lname" : "jiang",

"relationships" : [

    {
    

        "fname" : "qiang",

        "lname" : "he"

    },

    {
    

        "fname" : "xiong",

        "lname" : "lan"

    },


]

2.ddToSet比ne更好用,它可以自己判断数据是否存在,而且它和each结合使用,还能同时在数组中插入多个数据,这是ne没办法办到的

db.user.update({
    “_id” : ObjectId(4ffcb2ed65282ea95f7e3304”)},{
    addToSet:{
    "relationships":{
    each:[{
    “fname”:”xiong”,”lname”:”lan”},
{
    “fname”:”dongren”,”lname”:”zeng”}]}}})
"_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),

"age" : 23,

"favorite" : {
    

    "1" : "reading",

    "2" : "swimming",

    "3" : "listening music"

},

"fname" : "jeff",

"height" : 166,

"lname" : "jiang",

"relationships" : [

    {
    

        "fname" : "qiang",

        "lname" : "he"

    },

    {
    

        "fname" : "xiong",

        "lname" : "lan"

    },

    {
    

        "fname" : "xiong",

        "lname" : "lan"

    },

    {
    

        "fname" : "dongren",

        "lname" : "zeng"

    }

]

在修改语句中,我们想同时插入{“fname”:”xiong”,”lname”:”lan”},

{“fname”:”dongren”,”lname”:”zeng”}两个数据,但在原数组中,
{“fname”:”xiong”,”lname”:”lan”}这个数据已经存在,所以它只插入了后面那条。达到了我们想要的目的。所以,我个人更喜欢使用$addToSet

6.对其中的一部分进行操作

有时候数组有多个值,而我们只想对其中的一部分进行操作。如果我们把整个文档都抄下来,那太麻烦也太愚蠢了。好在mongodb给我们提供了两种简便方法:通过位置或者操作符“$”。下面我们来分别看看这两种方法怎么使用。首先是通过数组位置来操作。数组都是以0开头的,可以将下标直接作为键来选择元素。例如,我们想给数组的第一个数据加上年龄键值对,我们可以这么操作:

 db.user.update({
    “_id” : ObjectId(4ffcb2ed65282ea95f7e3304”)},{
    $set:{
    “relationships.0.age”:22}})
"_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),

"age" : 23,

"favorite" : {
    

    "1" : "reading",

    "2" : "swimming",

    "3" : "listening music"

},

"fname" : "jeff",

"height" : 166,

"lname" : "jiang",

"relationships" : [

    {
    

        "age" : 22,

        "fname" : "qiang",

        "lname" : "he"

    },

    {
    

        "fname" : "deng",

        "lname" : "pan"

    },

    {
    

        "fname" : "xiong",

        "lname" : "lan"

    }

]

可是很多情况下,不预先查询文档我们就不知道要修改数组的元素的下标。这时定位操作符“$”就很好用了。它就是用来定位查询文档已匹配的元素,并进行更新。我们来看看它怎么用:

db.user.update({
    “relationships.fname”:”xiong”},{
    set:{
    "relationships..age”:22}})
"_id" : ObjectId("4ffcb2ed65282ea95f7e3304"),

"age" : 23,

"favorite" : {
    

    "1" : "reading",

    "2" : "swimming",

    "3" : "listening music"

},

"fname" : "jeff",

"height" : 166,

"lname" : "jiang",

"relationships" : [

    {
    

        "age" : 22,

        "fname" : "qiang",

        "lname" : "he"

    },

    {
    

        "age" : 22,

        "fname" : "deng",

        "lname" : "pan"

    },

    {
    

        "age" : 22,

        "fname" : "xiong",

        "lname" : "lan"

    }

]

7 mongodb中$的作用

定义

定位符$的确定数组中一个要被更新的元素的位置,而不用具体指定该元素在数组中的位置。
用法

1.更新数组中的值
1)语法格式

{
    "<array>.$": value}

2)示例
创建集合students有以下文档:

db.students.insert([
   {
     "_id" : 1, "grades" : [ 85, 80, 80 ] },
   {
     "_id" : 2, "grades" : [ 88, 90, 92 ] },
   {
     "_id" : 3, "grades" : [ 85, 100, 90 ] }
])

将grades数组中第一个值为80更新为82,如果你不知道第一个值的具体位置,就可以像下面这样写:

db.students.updateOne(
   {
     _id: 1, grades: 80 },
   {
     $set: {
     "grades.$" : 82 } }
)

定位符$像一个占位符,匹配第一个符合查询条件的值的位置。
2.更新数组中的文档
定位符为更新那些包含嵌入文档的数组提供了方便。要取得嵌入文档中的字段属性值,在后面使用点符号。如一下语法格式描述

1)语法格式

db.collection.update(
   {
     <query selector> },
   {
     <update operator>: {
     "array.$.field" : value } }
)

2)举例
假设students集合中grades数组包含以下嵌入的文档:

{
    
  _id: 4,
  grades: [
     {
     grade: 80, mean: 75, std: 8 },
     {
     grade: 85, mean: 90, std: 5 },
     {
     grade: 85, mean: 85, std: 8 }
  ]
}

使用$定位符去更新grades数组中文档中字段std的值,被更新的文档是第一个匹配grade值为85的文档。如下:

db.students.updateOne(
   {
     _id: 4, "grades.grade": 85 },
   {
     $set: {
     "grades.$.std" : 6 } }
)

更新后的结果为:

{
    
   "_id" : 4,
   "grades" : [
      {
     "grade" : 80, "mean" : 75, "std" : 8 },
      {
     "grade" : 85, "mean" : 90, "std" : 6 },
      {
     "grade" : 85, "mean" : 85, "std" : 8 }
   ]
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_46535940/article/details/109363792

智能推荐

使用 gitee+sphinx+readthedocs 搭建个人博客_添加readthedocs项目-程序员宅基地

文章浏览阅读1.1k次,点赞21次,收藏25次。gitee,是国内免费的代码托管平台,相比github在国内,有更快的访问速度,全中文界面,对国人,更友好。sphinx,是一个功能强大的文档生成器,具有许多用于编写技术文档的强大功能。readthedocs,是一个免费在线文档托管范围平台,可以使用二级域名显示个人博客。_添加readthedocs项目

详解Google Authenticator工作原理_authenticator 二维码 算法-程序员宅基地

文章浏览阅读5.5k次。详解Google Authenticator工作原理发表于2014-09-23 08:28| 10060次阅读| 来源CSDN| 16 条评论| 作者伍昆Google二维码Google Authenticator算法 摘要:Google Authenticator是谷歌推出的一款动态口令工具,旨在解决大家Google账户遭到恶意攻击的问题。那么,Authen_authenticator 二维码 算法

普通函数和箭头函数之间的区别_箭头函数和普通函数之间如何转换-程序员宅基地

文章浏览阅读1k次。I.普通函数和ES6的箭头函数除了this指向不同之外还有什么不同?A.箭头函数作为匿名函数,不能作为构造函数,不能使用new关键字B.箭头函数不绑定arguments,用rest参数...解决C.箭头函数会捕获其上下文的this值,作为自己的this值D.箭头函数当方法使用,没有定义this的绑定E.使用call()和apply()调用,传入参数时,参数一的改变对this没有..._箭头函数和普通函数之间如何转换

如果结束进程拒绝访问,可以尝试以下-程序员宅基地

文章浏览阅读2.3k次。如果taskkill /f /pid 123 出现拒绝访问时,可使用以下方式删除进程:wmic process where name=‘qq.exe’ delete11如果这样还杀不死,恐怕就要进[安全模式]删除了。杀了进程,想删除文件,可以这样删除cmd下运行:DEL /F /A /Q 文件名抄自-吉吉教主...

Visual Studio-IIS Express 支持局域网访问配置-程序员宅基地

文章浏览阅读201次。转自:http://www.itnose.net/detail/6132793.html使用Visual Studio开发Web网页的时候有这样的情况:想要在调试模式下让局域网的其他设备进行访问,以便进行测试。虽然可以部署到服务器中,但是却无法进行调试,就算是注入进程进行调试也是无法达到自己的需求;所以只能在Visual Studio-IIS Express 中进行调试。而于此将..._visual studio iis express debug localhost

Oracle 数据库层级遍历查询_oracle遍历查询结果集-程序员宅基地

文章浏览阅读1.5k次。首先创建一张用于测试的表,表明为 TREE,表中有3个字段,分别是,ID,NANE,UP_ID。UP_ID 是 ID 的上层,主要实现树形结构的存储。1.1 初始化测试数据1.1.1 写入数据1.1.2 树形结构如下图root(8)一(1)二(2)三(3)五(5)root(6)四(4)2. 树形结构遍历查询2.1 从父节点遍历查询结果如下:2.2 从子节点开始遍历查询结果是:2.3 start with 条件 connect by prior_oracle遍历查询结果集

随便推点

解卷积的维度计算_转置卷积pad多少是整数倍-程序员宅基地

文章浏览阅读4.5k次。解卷积(deconvolution)或者反卷积,类似于卷积的逆运算;如果按照严格的数学公式来叫,应该叫做“转置卷积(transpose convolution)”。解卷积最直观的作用是扩大feature map的分辨率,在语义分割任务中被广泛使用。解卷积的维度计算公式如下: w_new = stride*w - 2*pad + (kernel-stride) 从上面的公式可以看到:与卷积相..._转置卷积pad多少是整数倍

linux 块设备子系统,Linux块设备IO子系统(二) _页高速缓存-程序员宅基地

文章浏览阅读143次。磁盘驱动就是实现磁盘空间和内存空间数据上的交互,在上一篇中我们讨论了内存端的Page Segment Block Sector相关的概念,本文以3.14内核为例,讨论这部分内存是如何被组织管理的。我们知道,为了解决CPU和内存的速度不匹配,计算机系统引入了Cache缓存机制,这种硬件Cache的速度接近CPU内部寄存器的速度,可以提高系统效率,同样的思路也适用于解决内存和磁盘的速度不匹配问题,此外..._linux块设备io子系统(二)

狂神说SpringBoot07:整合JDBC-程序员宅基地

文章浏览阅读4.9k次,点赞12次,收藏48次。狂神说SpringBoot系列连载课程,通俗易懂,基于SpringBoot2.2.5版本,欢迎各位狂粉转发关注学习。未经作者授权,禁止转载SpringData简介对于数据访问层,无论是 ...

flash_镁光mt25qu01的擦除时序要求-程序员宅基地

文章浏览阅读377次。记录flash 调试过程中的问题_镁光mt25qu01的擦除时序要求

竹云+巨杉丨互信认证 安全可靠_竹云iam 操作手册-程序员宅基地

文章浏览阅读2.3k次。近日,竹云IAM统一身份安全管理平台与巨杉数据库完成技术兼容和认证工作,经双方共同严格测试,巨杉数据库V3.4与竹云身份管理与访问控制平台软件V6.0,竹云安全内控管理平台软件V6.0在兼容性、可靠性和性能等方面均能满足用户的关键性应用需求,双方将共同打造基于分布式数据库的微服务架构身份管理与访问控制系统联合解决方案。随着国家对重点行业“安全可控信息技术”的要求不断深化,也越来越强调基于国产生态环境下信息系统的自主可控。作为拥有完全自主可控国产化技术的高新科技企业,竹云与巨杉的紧密合作将为用户提供更高效、_竹云iam 操作手册

c++中string和char*的类型转换,并求string的长度_c_str() 长度-程序员宅基地

文章浏览阅读1.5k次。一、char*(char)转string(直接赋值)#include<iostream>#include<string>#include <typeinfo>using namespace std;int main(){ string str; const char* p = "ch"; //char p[] = "ch"; str = p; cout << str << endl; _c_str() 长度