MongoDB学习笔记~对集合属性的操作

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介:

$unset清除元素

请注意在单个数组元素上使用$unset的结果可能与你设想的不一样。其结果只是将元素的值设置为null,而非删除整个元素。要想彻底删除某个数组元素,可以用$pull 和$pop操作符。

$addToSet和$push的区别

该两者的功能都是给数组添加一个值。但是两者之间有区别,$addToSet要添加的值如果不存在才进行添加操作,但是push只添加一个值;例如:

tags = [“zzl”,”dudu”]

如果执行db.collection.update({},{$push:{tag:"laozhao"}}) 结果就是 [“laozhao”,”zzl”,“dudu”]

如果执行db.collection.update({},{$addToSet:{tag:"zzl"}}) 结果不变

关于Update.Combine集合更新注意点

对于Update.Combine我们可以把需要更新的字段合并到列表List<UpdateDefinition<T>>()中,最后一起进行更新,而这对于集合属性来说,需要注意一下,我们需要为集合属性元素使用PushEach进行添加,而不是Push,因为使用Push会将前一个元素覆盖掉,而只保留最后的元素(集合里的),所以需要使用PushEach来代替它,代码如下:

        [TestMethod]
        public void Push()
        {
            var filter = Builders<Dog>.Filter.Eq(i => i.Id, "5850b0bdebb91a3184f90d3d");

            //更新所需要的字段
            var updateList = new List<UpdateDefinition<Dog>>();
            //更新需要集合类型的字段
            var dogHistoryList = new List<DogHistory>();
            //添加元素到集合属性
            dogHistoryList.Add(new DogHistory
                {
                    HistoryName = "四虎子3",
                    IsHealth = false,
                    Adderss = new Adderss("广东", "深圳", "沿海")
                });
            dogHistoryList.Add(new DogHistory
            {
                HistoryName = "四虎子4",
                IsHealth = false,
                Adderss = new Adderss("广东", "深圳", "沿海")
            });
            //将需要更新集合对象添加到updateList里
            updateList.Add(Builders<Dog>.Update.PushEach(i => i.DogHistory, dogHistoryList));

            MongoDbClient.MongoManager<Dog>.Instance.UpdateOne(
                filter,
               Builders<Dog>.Update.Combine(updateList));

        }

Update仓储的优化

大叔对于这一点,也把它封装到了Lind.DDD.Repositories.Mongo的仓储里,完善了Update操作,修改了之前的递归处理逻辑,代码反而更简洁了,原理就是使用$set直接把原数据覆盖即可。

        /// <summary>
        /// 版本二:递归构建Update操作串
        /// 主要功能:实现List子属性的push操作
        /// </summary>
        /// <param name="fieldList"></param>
        /// <param name="property"></param>
        /// <param name="propertyValue"></param>
        /// <param name="item"></param>
        /// <param name="father"></param>
        private void GenerateRecursionSet(
                  List<UpdateDefinition<TEntity>> fieldList,
                  PropertyInfo property,
                  object propertyValue,
                  TEntity item,
                  string father
           )
        {
            //复杂类型
            if (property.PropertyType.IsClass && property.PropertyType != typeof(string) && propertyValue != null)
            {
                //集合
                if (typeof(IList).IsAssignableFrom(propertyValue.GetType()))
                {
                    var arr = propertyValue as IList;
                    if (arr != null && arr.Count > 0)
                    {
                        if (string.IsNullOrWhiteSpace(father))
                            fieldList.Add(Builders<TEntity>.Update.Set(property.Name, arr));
                        else
                            fieldList.Add(Builders<TEntity>.Update.Set(father + "." + property.Name, arr));
                    }
                }
                //实体
                else
                {
                    foreach (var sub in property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
                    {
                        if (string.IsNullOrWhiteSpace(father))
                            GenerateRecursionSet(fieldList, sub, sub.GetValue(propertyValue), item, property.Name);
                        else
                            GenerateRecursionSet(fieldList, sub, sub.GetValue(propertyValue), item, father + "." + property.Name);
                    }
                }
            }
            //简单类型
            else
            {
                if (property.Name != EntityKey)//更新集中不能有实体键_id
                {
                    if (string.IsNullOrWhiteSpace(father))
                        fieldList.Add(Builders<TEntity>.Update.Set(property.Name, propertyValue));
                    else
                        fieldList.Add(Builders<TEntity>.Update.Set(father + "." + property.Name, propertyValue));

                }
            }
        }

对于产生的结果是我们可以接受的,可以对集合属性很方便的实现更新了。

            dog.Des.Worker = new string[] { "engineer", "coder" };
            dog.Des.Address = new List<Adderss>
            {
               new Adderss("beijing","fangshan","liangxiang",new string[]{"zhaojiaogan","Road100","No.300"}),
               new Adderss("北京","大兴","西红门",new string[]{"理想城","大满贯","4号楼"}),
             }

产生的结果如下

以上数据结构应该算是比较复杂的了,像实体里有子实体,然后子实体里有集合,集合里又有数组,但我封装的更新还是都适用的,这点已经做过测试,请放心使用!

欢迎大家继续关注mongodb技术!

继续关注大叔博客!

本文转自博客园张占岭(仓储大叔)的博客,原文链接:MongoDB学习笔记~对集合属性的操作,如需转载请自行联系原博主。

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
2月前
|
NoSQL MongoDB 数据库
MongoDB 删除集合
10月更文挑战第14天
44 1
|
1月前
|
缓存 NoSQL MongoDB
|
2月前
|
存储 NoSQL MongoDB
MongoDB 创建集合
10月更文挑战第13天
35 1
|
7月前
|
JSON NoSQL MongoDB
实时计算 Flink版产品使用合集之要将收集到的 MongoDB 数据映射成 JSON 对象而非按字段分割,该怎么操作
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
5月前
|
DataWorks NoSQL fastjson
DataWorks操作报错合集之DataX进行MongoDB全量迁移的过程中,DataX的MongoDB Reader插件在初始化阶段找不到Fastjson 2.x版本的类库,该怎么办
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
4月前
|
存储 NoSQL 数据管理
揭秘MongoDB时间序列集合:这个超级功能将如何彻底改变你的数据管理?
【8月更文挑战第8天】时间序列数据记录随时间变化的信息,在数据库管理中至关重要。MongoDB自4.0版起引入时间序列集合,专为这类数据优化存储与查询。通过问答形式介绍其特点:自动数据过期、高效存储机制及快速查询操作。创建时需指定时间字段及可选元数据字段。支持设置数据过期时间,采用粗粒度索引减少I/O操作。查询时可通过时间范围筛选数据,并利用聚合框架进行数据分析。随着实时分析需求的增长,时间序列集合的应用将更加广泛。
198 0
|
6月前
|
存储 NoSQL Linux
【MongoDB】下载安装、指令操作
【MongoDB】下载安装、指令操作
197 1
|
6月前
|
分布式计算 DataWorks NoSQL
DataWorks操作报错合集之从MongoDB同步数据到MaxCompute(ODPS)时,出现报错,该怎么解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
DataWorks操作报错合集之从MongoDB同步数据到MaxCompute(ODPS)时,出现报错,该怎么解决
|
6月前
|
存储 NoSQL 数据挖掘
深入探索MongoDB聚合操作:解析数据之美
深入探索MongoDB聚合操作:解析数据之美
220 1
|
6月前
|
NoSQL Shell MongoDB
python操作MongoDB部分
python操作MongoDB部分
40 0