source

다시 삽입하지 않고 PyMongo의 MongoDB 문서 배열에 항목 추가

manysource 2023. 7. 19. 21:26

다시 삽입하지 않고 PyMongo의 MongoDB 문서 배열에 항목 추가

저는 Python 웹 애플리케이션(PyMongo + Bottle)의 백엔드 데이터베이스로 MongoDB를 사용하고 있습니다.사용자는 파일을 업로드하고 업로드하는 동안 선택적으로 이러한 파일에 태그를 지정할 수 있습니다.태그는 아래와 같이 문서 내의 목록으로 저장됩니다.

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

사용자가 문서에 새 태그를 추가할 수 있도록 허용하려고 합니다.저는 다음과 같은 것을 생각해냈습니다.

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)

(fyi;ref키는 항상 고유합니다.이것은 쉽게 될 수 있습니다._id또한.)문서 전체를 뒤로 빼다 다시 삽입하지 않고 '태그' 값만 직접 업데이트하는 방법이 있어야 할 것 같습니다.내가 뭘 빠트렸나요?

어떤 생각이든 매우 감사합니다 :)

먼저 문서를 검색하는 데 사용할 필요가 없습니다..update연산자를 사용하는 방법.

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

업데이트가 더 이상 사용되지 않으므로 pymongo 2.9 이상을 사용하는 경우 또는 방법을 사용해야 합니다.

@sytvane 답변에 추가하고 @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)

간단하게 할 수 있습니다.

단일 항목을 추가하려는 경우

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"
}

여러 항목을 추가하려는 경우

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가 새 키를 만듭니다.

몇 가지 정답이 있었지만, 제 생각에는 update_tags를 이렇게 쓰는 것이 더 낫고 더 유용합니다.

def update_tags(ref, *args):
    coll.update_one(ref, {'$push': {'tags': {'$each': args}}})

이렇게 하면 하나의 태그를 추가하거나 여러 개의 태그를 추가할 수 있습니다.

>> update_tags(ref, 'tag5')
>> update_tags(ref, 'tag5', 'tag6')
>> list_of_new_tags = do_something_that_returns_list_of_tags()
>> update_tags(ref, *list_of_new_tags)

사용할 수 있습니다.$push

collection_name.update_one({'ref': ref}, {'$push': {'tags': new_tag}})

단일 쿼리에서 여러 어레이를 업데이트할 수 있습니다.

collection_name.update_one({'ref': ref}, {'$push': {'field1': value1, 'filed2': value2}})

아래와 같이 값을 눌러 누를 수 있습니다.

{ $push: { <field1>: <value1>, ... } }

언급URL : https://stackoverflow.com/questions/33189258/append-item-to-mongodb-document-array-in-pymongo-without-re-insertion