2015-10-17 73 views
8

我使用MongoDB作为Python Web应用程序(PyMongo + Bottle)的后端数据库。用户可以上传文件并选择“标记”这些文件。这些标签按照以下方式存储在文档中:将项目添加到PyMongo中的MongoDB文档数组而不重新插入

{ 
    "_id" : ObjectId("561c199e038e42b10956e3fc"), 
    "tags" : [ "tag1", "tag2", "tag3" ], 
    "ref" : "4780" 
} 

我试图让用户在任何文档中追加新标签。我想出了这样的事情:(。FYI; ref关键始终是唯一的,这可能很容易被_id以及)

def update_tags(ref, new_tag) 
    # fetch desired document by ref key as dict 
    document = dict(coll.find_one({'ref': ref})) 
    # append new tag 
    document['tags'].append(new_tag) 
    # re-insert the document back into mongo 
    coll.update(document) 

好像应该有一个办法只有更新“标签”值直接不用拉回整个文件并重新插入。我在这里错过了什么吗?

任何想法是极大的赞赏:)

回答

12

你并不需要使用首先检索该文件只是用.update方法与$push运营商。

def update_tags(ref, new_tag): 
    coll.update({'ref': ref}, {'$push': {'tags': new_tag}}) 

由于更新已经过时,你应该,如果你正在使用pymongo 2.9或更新版本

+1

两者有什么区别?只是返回值(文档vs UpdateResult对象)?你什么时候使用其中一种? – stackoverflowwww

+4

如果'标签'字段不存在会发生什么? –

+0

如果'tags'字段不存在,则会创建它。 @GauravOjha – styvane

0

只需添加到@ssytvane答案使用find_one_and_updateupdate_one方法,并回答@Guarav:您可以添加“ UPSERT = TRUE”,如果它不存在:

def update_tags(ref, new_tag): 
    coll.update({'ref': ref}, {'$push': {'tags': new_tag}}, upsert = True) 

def update_tags(ref, new_tag): 
    coll.update_one({'ref': ref}, {'$push': {'tags': new_tag}}, upsert = True) 
+0

感谢您对Stack Overflow的贡献。请注意,仅限代码答案是因为他们没有解释他们如何解决问题而不鼓励。请不要参考其他答案/评论,而应考虑更新答案,以解释其做法和解决方法,以便它是一个独立答案,并且在其他答案或评论被移除的情况下仍然有意义。 – FluffyKitten

1

你可以简单地做

1)如果你想添加一个条目

def update_tags(ref, new_tag): 
    coll.update({'ref': ref}, {'$push': {'tags': new_tag}}) 

如:

{ 
    "_id" : ObjectId("561c199e038e42b10956e3fc"), 
    "tags" : [ "tag1", "tag2", "tag3" ], 
    "ref" : "4780" 
} 
>> update_tags("4780", "tag4") 
{'updatedExisting': True, u'nModified': 1, u'ok': 1, u'n': 1} 
>> coll.find_one({"ref":"4780"}) 
{ 
    "_id" : ObjectId("561c199e038e42b10956e3fc"), 
    "tags" : [ "tag1", "tag2", "tag3" , "tag4" ], 
    "ref" : "4780" 
} 

2)如果要追加多个条目

def update_tags(ref, new_tag): 
    coll.update({'ref': ref}, {'$pushAll': {'tags': new_tag}}) #type of new_tag is list 

例如:

{ 
    "_id" : ObjectId("561c199e038e42b10956e3fc"), 
    "tags" : [ "tag1", "tag2", "tag3" ], 
    "ref" : "4780" 
} 
>> update_tags("4780", ["tag5", "tag6", "tag7"]) 
{'updatedExisting': True, u'nModified': 1, u'ok': 1, u'n': 1} 
>> coll.find_one({"ref":"4780"}) 
{ 
    "_id" : ObjectId("561c199e038e42b10956e3fc"), 
    "tags" : [ "tag1", "tag2", "tag3" , "tag4" , "tag5", "tag6", "tag7" ], 
    "ref" : "4780" 
} 

注意:如果密钥不存在,mongo会创建新的密钥。

相关问题