如何修改MONGODB字段的数组,不用整个字段修改
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何修改MONGODB字段的数组,不用整个字段修改相关的知识,希望对你有一定的参考价值。
很好的一点就是,数据库不需要先建立,在连接后,如果进行插入数据操作,系统可以自己创建,我们假设一个post集合,里面是一些博客文章组成的文档。下面先插入几篇文章做实验。1 >>> import datetime 2 >>> post1 = "title":"I Love Python", 3 "slug":"i-love-python", 4 "author":"SErHo", 5 "content":"I Love Python....", 6 "tags":["Love","Python"], 7 "time":datetime.datetime.now() 8 9 >>> post2 = "title":"Python and MongoDB", 10 "slug":"python-mongodb", 11 "author":"SErHo", 12 "content":"Python and MongoDB....", 13 "tags":["Python","MongoDB"], 14 "time":datetime.datetime.now() 15 16 >>> post3 = "title":"SErHo Blog", 17 "slug":"serho-blog", 18 "author":"Akio", 19 "content":"SErHo Blog is OK....", 20 "tags":["SErHo","Blog"], 21 "time":datetime.datetime.now() 22 23 >>> posts.insert(post1) 24 >>> posts.insert(post2) 25 >>> posts.insert(post3)
在插入一个文档时,MongoDB会自动给每个文档增加一个”_id”的键,这个键是通过复杂计算出来的,不会重复,类似于下面这样的:
1 ObjectId('4ea0207dd483050fe8000001')
增加数据就是这样的简单,不需要事先定义文档的机构,每个文档的结构也可以不一样,上面我举的例子是一样的,这可以根据实际需求来设置,我这个是为了好讲解下面的。插入过后,肯定最先的是查询,下面查询出post集合里面的所有文档:
1 >>> posts = posts.find() 2 >>> count = posts.count() 3 >>> for post in posts: 4 print post
数据库使用游标来返回find的结果,游标上有多种方法,比如上面的count(),就可以得到查询到的文档总数。这个例子将返回”count=3″和上面的那三篇文档。更多查询方法在后面将讲解,这些方法更加强大。
插入过后可能发现需要修改,于是下面讲解一些修改的方法。如果需要大幅度的修改,什么是大幅度的修改呢,比如把post1的title,slug,author等都修改了,我的理解就是大于一个键的修改就叫大幅修改。修改一个东西,你得先找到他,所以查询方法就很重要了,不幸的是,这个准备后面才将。我们先随便查找一个来修改吧。
1 >>> post = posts.find_one("slug":"python-mongodb") 2 >>> post["author"] 3 u'SErHo' 4 >>> post["author"] = "HaHa Lu" 5 >>> post["title"] = "Test Update" 6 >>> post["title"] = "Test Update" 7 >>> post["_id"] 8 ObjectId('4ea0207dd483050fe8000001') 9 >>> posts.update("_id":post["_id"],post) 10 >>> post = posts.find_one("_id":post["_id"]) 11 >>> print post 12 u'author': u'HaHa Lu', u'title': u'Test Update', 13 u'tags': [u'Python', u'MongoDB'], 14 u'content': u'Python and MongoDB....', 15 u'time': datetime.datetime(2011, 10, 20, 21, 21, 52, 818000), 16 u'_id': ObjectId('4ea0207dd483050fe8000001'), 17 u'slug': u'python-mongodb'
首先我们根据slug来获得一篇文章,然后可以通过Python字典访问方法得到键的值,然后重新设置,再对post集合进行更新,在对整个集合进行更新时,你得先匹配要更改的文档,利用_id这个属性来更新是比较常用的方法,因为你其他改了,这个可改不了。在执行update中最常见的错误就是限制的条件找到了多个文档,如果这样,数据库就不会更新这个集合,所有最好使用_id来匹配。
如果只更新一个键呢,那就不用这么大费周折了,可以使用”$set”这个修改器,指定一个键,如果不存在,就可以创建。比如我要继续更新上面那篇文章的content,可以这样做(记住,修改它,必须先找到它,这里我利用上面查询到的_id值来找):
1 >>> posts.update("_id":post["_id"],"$set": 2 "content":"Test Update SET....")
MongoDB的修改是很强大的,你可以把数据类型也给改了,比如把tags的数组改成普通的字符串。”$set”过后又想删除这个键,可以使用”$unset”。如果我的这个post里面有一个键是views,即文章访问的次数,我想在每次访问这个文章后给它的值增加1,这该怎么办?于是”$inc”修改器出场了,这个可以用来增加已有键的值,如果没有,则创建它,类似的用法是:
1 2 >>> posts.update("_id":post["_id"],"$inc": "views":1)
如果想修改tags这个数组里面的内容怎么办?有一个办法就是用$set整体修改,但只是改里面的一些元素呢,MongoDB准备好了用于数组的修改器。比如,想要在tags里面加一个”Test”,这需要使用”$push”,它可以在数组末尾添加一个元素:
1 >>> posts.update("_id":post["_id"],"$push":"tags":"Test")
为了避免加入了重复的,可以将”$push”改为使用”$addToSet”,如果需要添加多个值,可以配合”$each”来使用,这样就可以添加不重复的进去,如下面:
1 2 >>> posts.update("_id":post["_id"],"$addToSet": 3 "tags":"$each":["Python","Each"])
说完了添加,下面是删除,可以把数组看成栈和队列,使用”$pop”来操作,比如上面的:
1 >>> posts.update("_id":post["_id"],"$pop":"tags":1)
这个会删除tags里面最后一个,改成-1则删除第一个。可以使用”$pull”来删除数组中指定的值,它会删除数组中所有匹配的值。如何修改其中的一个值呢?可以先删除掉,再增加一个进去,还有就是直接定位修改。比如tags数组中,”Python”是第一个,想把它改成”python”,可以通过下标直接选择,就是tags[0],然后使用上面的”$set”等修改器,如果不确定可以使用$来定位:
1 >>> posts.update("tags":"MongoDB","$set":"tags.$":"Hello")
这个将先搜索tags中满足”MongoDB”的,如果找到,就把它修改为”Hello”。可以看到上面的update这个函数已经有两个参数了,它还有第3个参数upsert,如果设为”True”,则如果没有找到匹配的文档,就会在匹配的基础上新建一个文档,具体实例就不讲了。 参考技术A node.js更新mongodb数组字段可以参考官方指南 http://docs.mongodb.org/manual/reference/operator/update/positional/#up._S_ 提供一个小的案例代码:
MongoDB增加及修改字段,表关联修改字段方法一则
需求是为集合(表)'customerfeature1’增加’abnormal’字段,根据条件分别设置1或0。
1. 增加及修改字段
MongoDB 更新文档,使用 update() 和 save() 方法来更新集合中的文档。本文只介绍update()方法。update() 方法用于更新已存在的文档。语法格式如下:
db.collection.update(
<query>,
<update>,
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
)
参数说明:
- query : update的查询条件,类似sql update查询内where后面的。
- update : update的对象和一些更新的操作符(如 , , ,inc…)等,也可以理解为sql update查询内set后面的
- upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
- multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
- writeConcern :可选,抛出异常的级别。
增加字段与修改字段,在语法上是等效的,例如增加’abnormal’字段,初始化为“0”:
db.getCollection('customerfeature1').update(,'$set':'abnormal':0,'multi':true)
注:multi是必须的,如果不配置true, 默认只有第一列新增了
2. 表关联修改数据
由于没有找到MongoDB直接表关联修改数据,则采用JavaScript脚本方式处理,例如依据集合(表)'excludeddata’中的carduser_id相同,修改abnormal字段的值为1:
var c = db.getCollection('excludeddata').find(,"carduser_id":1)
while(c.hasNext())
str = c.next()
carduser_id = str.carduser_id
db.getCollection('customerfeature1').update('carduser_id':carduser_id,'$set':'abnormal':1,'multi':true)
printjson(carduser_id);
注:代码在Robo 3T 1.4.2 Shell下执行。
3. 其他
3.1. 取最大值
例如取最大月份方法:
db.getCollection('customerfeature').find().sort('yearmonth':-1).limit(1)
3.2. 或条件查询表达方式
db.getCollection('customerfeature1').find('$or':['lasttradecount':'$lte':3,'monthnum':'lt':2]).count()
参考:
肖永威. 如何将mongo查询结果导出到文件中以及导入到另一个Mongo库中.CSDN博客. 2019.03
以上是关于如何修改MONGODB字段的数组,不用整个字段修改的主要内容,如果未能解决你的问题,请参考以下文章