MongoDB数组修改器更新数据

2024-06-20 03:18

本文主要是介绍MongoDB数组修改器更新数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

MongoDB数组修改器更新数据
这里,我们将了解一下数组修改器。数组,是我们经常看到和使用到的且非常有用的数据结构:它不仅可以通过索进行引用,还可以作为集合来使用。数组修改器,顾名思义,它是用来修改数组的,而不能用来修改整数或者字符串。数组修改器不多,就那么几个,但熟练掌握它后,将给我们带来非常方便的操作。下面,我们来了解一下:
> db.user.findOne()
{
"_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"
}
]
}
以上是我的还在完善中的个人信息文档。假设最近我又交了一个好朋友,我想把他加到我的人际关系“relationships”数组中。这时,$push修改器就派上用场了。$push的作用就是,如果指定的键已经存在,它会向已有的数组末尾加入一个元素,要是没有就会创建一个新的数组。下面我们把新朋友加进去。
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$push:{"relationships":{"fname":"xiong","lname":"lan"}}})
> db.user.findOne()
{
"_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"
}
]
}
有加就有减,那么怎么对数组进行“减”操作呢。能达到对数组“减”目的的修改器有两个,$pop和$pull。$pop和$pull又有区别,我们来分别实验。首先是$pop
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$pop:{"relationships":1}})
> db.user.findOne()
{
"_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"
}
]
}
从上面可以看出,它把我们刚加进去的朋友又删除了,也就是说它从数组的最后删除。那么,如果我们想从数组的开头删除该怎么办呢。很简单,把上面的“1”改成“-1”,它将逆向操作。下面看一下:
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$pop:{"relationships":-1}})
> db.user.findOne()
{
"_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"
}
]
}
从结果可以看出,它达到了我们预期的目的。那么如果我们想删除数组中间的呢。这时,$pull派上用场。首先,我们先将新朋友加进去,这里我不再演示。但我们可以想到“dongren”这个人是在数组的中间。现在我们要将他删除:
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$pull:{"relationships":{"fname":"dongren","lname":"zeng"}}})
> db.user.findOne()
{
"_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"
}
]
}
从上面可以看出,$pull可以将数组中间的数据删除。这里还有一点要注意,$pull会将所有匹配到的数据都删除,这里我就不做实验了。下面,我们再来看看$push还有什么特点,我们再往数组里插入一相同的数据,看看会如何:
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$push:{"relationships":{"fname":"xiong","lname":"lan"}}})
> db.user.findOne()
{
"_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"
}
]
}
结果表明,它是能正常插入到数组的。而在实际生产环境中,我们都不想看到这样的结果,那么,这里又出现了两个可以用的修改器:$ne和$addToSet。$ne主要拿来判断,若数组里面有这个值,则不插入;没有才插入。
> db.user.update({"relationships.fname":{$ne:"xiong"}},{$set:{"fname":"xiong","lname":"lan"}})
> db.user.findOne()
{
"_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"
}
]
}
由结果可以看出,由于该数据在数组中已经存在,所以不再插入。其实,$addToSet比$ne更好用,它可以自己判断数据是否存在,而且它和$each结合使用,还能同时在数组中插入多个数据,这是$ne没办法办到的,下面我们来看一下$addToSet的用法,这里顺便结合了$each的使用:
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},
{$addToSet:{"relationships":{$each:[{"fname":"xiong","lname":"lan"},
{"fname":"dongren","lname":"zeng"}]}}})
> db.user.findOne()
{
"_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。
有时候数组有多个值,而我们只想对其中的一部分进行操作。如果我们把整个文档都抄下来,那太麻烦也太愚蠢了。好在mongodb给我们提供了两种简便方法:通过位置或者操作符“$”。下面我们来分别看看这两种方法怎么使用。首先是通过数组位置来操作。数组都是以0开头的,可以将下标直接作为键来选择元素。例如,我们想给数组的第一个数据加上年龄键值对,我们可以这么操作:
> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$set:{"relationships.0.age":22}})
> db.user.findOne()
{
"_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}})
> db.user.findOne()
{
"_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"
}
]
}

这篇关于MongoDB数组修改器更新数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1076954

相关文章

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

java如何实现高并发场景下三级缓存的数据一致性

《java如何实现高并发场景下三级缓存的数据一致性》这篇文章主要为大家详细介绍了java如何实现高并发场景下三级缓存的数据一致性,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 下面代码是一个使用Java和Redisson实现的三级缓存服务,主要功能包括:1.缓存结构:本地缓存:使

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

C#解析JSON数据全攻略指南

《C#解析JSON数据全攻略指南》这篇文章主要为大家详细介绍了使用C#解析JSON数据全攻略指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、为什么jsON是C#开发必修课?二、四步搞定网络JSON数据1. 获取数据 - HttpClient最佳实践2. 动态解析 - 快速

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问