`
ppxieppp
  • 浏览: 50708 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

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"
        }
    ]
}
有关数组的常用的修改器的用法就写到这里。可能例子用得不是很恰当,但通过这些例子,我觉得至少能对这些修改器的作用有个大致的了解。不妥甚至不对的地方,欢迎大神们拍砖。

本文出自 “上下求索者” 博客,请务必保留此出处http://jzfjeff.blog.51cto.com/1478834/1003191

分享到:
评论

相关推荐

    Mybatis拦截器记录数据更新历史记录到MongoDB

    本文将深入探讨如何使用Mybatis拦截器来记录数据更新历史记录,并将其存储到MongoDB中。 首先,我们来理解Mybatis拦截器的原理。Mybatis的拦截器是基于Java的动态代理机制实现的,它允许我们在特定的执行点(如SQL...

    Thinkphp使用mongodb数据库实现多条件查询方法

    MongoDB是一种NoSQL数据库,它存储数据的方式不同于传统的表格方式,而是将数据存储在BSON格式的文档中。在Thinkphp中使用MongoDB进行多条件查询时,需要对框架提供的驱动进行一定的修改以适应MongoDB的查询方式。 ...

    MongoDB中文档的更新操作示例详解

    本篇文章将深入探讨MongoDB中文档的更新操作,包括如何替换文档、处理多条匹配记录的更新以及使用修改器进行细粒度的字段更新。 首先,文档替换是一种常见的更新操作,当需要改变文档结构或整体内容时使用。例如,...

    Centos7下安装MongoDB

    7. 快速就地更新:查询优化器会分析查询表达式,并生成一个高效的查询计划。 8. 高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)。 安装MongoDB需要安装mongodb-org元数据包,该包包含四个组件包:...

    mongodb学习笔记

    MongoDB 中可以使用 `update` 方法来更新文档,例如 `db.[documentName].update({查询器},{修改器})`。强硬的更新会用新的文档代替老的文档。但是,需要注意的是,如果更新的文档和已有的文档 ID 冲突,那么系统会...

    MongoDB增删查改

    2. **局部更新**:使用`$inc`和`$set`修改器进行特定字段的更新: - `$inc`:增加或减少字段值,如`db.users.updateOne({name: 'John'}, { $inc: {age: 1}})`,若字段不存在,会自动创建并设置初始值。 - `$set`:...

    mongodb 修改器($inc/$set/$unset/$push/$pop/upsert)

    在处理文档更新时,除了完全替换整个文档之外,MongoDB 提供了一组原子性的更新修改器,这些修改器允许对文档的特定部分进行高效更新,确保数据的一致性。以下是几个主要的更新修改器的详细说明: 1. **$inc**: $...

    MongoDB常用的查询更新等操作汇总

    更新操作通常使用 `updateOne` 或 `updateMany` 方法,配合修改器如 `$set`, `$push`, `$pull` 等来更新文档的特定字段或数组元素。 这些只是MongoDB查询和更新操作的基础。MongoDB还提供了丰富的聚合框架、地理...

    mongodb数据库的一些简单实用

    修改器是 MongoDB 中用于更新文档的特殊关键字,例如 `$set`、`$inc` 等。 - `$set` 用于更新字段的值: ```javascript db.stu.update({name:"zxg"},{$set:{name:"xialan"}}) ``` - `$inc` 用于对数字类型的...

    Packt.Pentaho Analytics for MongoDB.2014(非正式)

    本篇内容讲述的是如何使用Pentaho和MongoDB构建数据分析系统,系统性地介绍了MongoDB的基础知识、Pentaho的使用方法,并针对数据整合、分析视图、报告设计、数据模型设计以及报告设计器中的提示和图表制作等方面提供...

    mongodb使用文档集

    在`/etc/mongod.conf`(Linux)或`C:\Program Files\MongoDB\Server\X.X\bin\mongod.cfg`(Windows)中修改配置文件,设置`dataDir`为数据存储路径,`logPath`为日志文件路径。然后使用`mongod`命令启动服务。 二、...

    mongodb和Robo3t.zip

    文档可以包含嵌套的文档、数组和其他复杂数据结构,适应现代应用程序的数据模型。 2. **集合与数据库**:在MongoDB中,数据库是数据的逻辑容器,类似于关系型数据库的数据库。集合是文档的集合,类似于表,但没有...

    MongoDB的创建、更新和删除

    更新操作在MongoDB中通常包括查询条件和修改器。例如,更新名字为`bob`的用户年龄加1: ```javascript db.users.update({"name":"bob"},{$set:{"age":23}}) ``` `$set`是一个修改器,用于设置`age`字段的值。 #### ...

    MongoDB Driver -JAVA 2.5.3 API

    你可以指定过滤器来选择要更新的文档,并提供更新操作描述符来定义如何修改这些文档。 - **Delete**: `deleteOne()`和`deleteMany()`用于删除集合中的文档。同样,你可以使用过滤器来选择要删除的文档。 - **...

    深入云计算 MongoDB管理与开发实战详解pdf.part1

    3.3.2 使用修改器 3.3.3 upsert和save更新 3.3.4 修改多个文档 3.3.5 修改文档并返回修改后的文档 3.4 数据库响应 3.4.1 安全操作 3.4.2 捕获异常 3.5 客户端请求和MongoDB数据库连接 3.6 本...

Global site tag (gtag.js) - Google Analytics