首页 > 解决方案 > Pymongo 查找和更新问题

问题描述

背景 我正在制作一个应用程序,该应用程序通过 Discord 机器人获取输入,然后将输入放入 Google 文档中。在此过程中,我使用 Flask 和 Pymongo 来查找isNew属性设置为的文档true并将其发送回 Google Docs 脚本。完成后,我想将isNew文档的属性设置为false. 或者,我可以在发送之前将其设置为isNewfalse因为在我在 Flask 中返回响应之后,我无法成功调用函数。

根据我的实验,每当我使用<CollectionName>.find()请求获取新文档并尝试isNew随后使用CollectionName.update_many()命令更新属性时,都会导致存储原始find命令文档的变量变为空白。

代码尝试:1.在尝试返回新文档时更新许多

import pymongo

# mongodb db connection string
connectionString = ('mongodb://localhost:27017')

client = pymongo.MongoClient(connectionString)
db = client['tempBotDB']

# 3 types of questions: quiz, cross, hunt
# separate collections for each type of strings

quizQs = db['quizQs']
crossQs = db['crossQs']
huntQs = db['huntQs']

# Properties of a question: isnew, type, question, answer


def saveQ(qObj):    # Saves a question to the db

    qType = qObj.get('type')

    # creating own qObj
    q = {
        'question': qObj.get('question'),
        'answer': qObj.get('answer'),
        'isNew': bool(True)
    }

    if qType == 'quiz':
        result = quizQs.insert_one(q)
    elif qType == 'cross':
        result = crossQs.insert_one(q)
    elif qType == 'hunt':
        result = huntQs.insert_one(q)
    else:
        result = ('Error: "type" of question can only be'
                  'one of : cross, hunt, quiz')
    return result


def getQs(qType):   # Gets all the questions by given type
    if qType == 'quiz':
        result = quizQs.update_many(
            {'isNew': bool(True)},
            {'$set': {'isNew': bool(False)}},
            {returnOriginal: True}
         )
        print(result)

    else:
        result = ('Error: "type" of question can only be'
                  'one of : cross, hunt, quiz')


getQs('quiz')

错误:NameError:未定义名称“returnOriginal”也尝试使用returnNewDocument而不是returnOriginal。但得到:NameError: name 'returnNewDocument' is not defined

  1. 在同一函数中使用查找后跟更新
def getQs(qType):   # Gets all the questions by given type
    if qType == 'quiz':

        selector = {'isNew': False}
        modifier = {'$set': {'isNew': True}}

        result = quizQs.find(selector)
        #fakeRes = quizQs.update_many(selector, modifier)

        print('res', result)
        for i in result:
            print('result', i)
        #print('fakeres', fakeRes)
        # for i in fakeRes:
        #     print('FakeRes', i)

    else:
        result = ('Error: "type" of question can only be'
                  'one of : cross, hunt, quiz')

如果我取消注释该update命令,则该命令的结果将find变为可合并(我收到一条错误消息),据我所知,这意味着它是空的。这是发生的事情:

def getQs(qType):   # Gets all the questions by given type
    if qType == 'quiz':

        selector = {'isNew': False}
        modifier = {'$set': {'isNew': True}}

        result = quizQs.find(selector)
        fakeRes = quizQs.update_many(selector, modifier)

        print('res', result)
        for i in result:
            print('result', i)
        print('fakeres', fakeRes)
        for i in fakeRes:
            print('FakeRes', i)

    else:
        result = ('Error: "type" of question can only be'
                  'one of : cross, hunt, quiz')

我得到以下输出:

res <pymongo.cursor.Cursor object at 0x10e34ca50>
fakeres <pymongo.results.UpdateResult object at 0x10e35bfa0>
Traceback (most recent call last):
  File "db.py", line 63, in <module>
    getQs('quiz')
  File "db.py", line 55, in getQs
    for i in fakeRes:
TypeError: 'UpdateResult' object is not iterable

注意遍历result对象是如何没有打印任何东西的,这表明它是空的。

所以,总而言之,我的主要问题是:我如何在 mongodb 中成功查找和更新多个文档,同时检索更新文档,或者只是找到的文档(未更新)[它们中的任何一个都可以工作,因为我不需要访问我更新的属性]

最后,在生成更新文档的字典列表并最终将该列表返回给用户时,首先对每个文档执行 afind和然后是合乎逻辑的吗?update_one

我真的很感激任何帮助。

标签: mongodbflaskpymongo

解决方案


有几种方法可以做到这一点,但您无法从 update_many 获取更新文档的列表 - Mongo 不支持。

所以你最好的方法是:

for record in db.mycollection.find({'isNew': False}):
    result = db.mycollection.update_one({'_id': record['_id']}, {'$set': {'isNew': True}})
    print(record)
    # Add in logic here  to assemble records for return to the user

推荐阅读