MongoDB返回“之前”和“之后”文档

时间:2018-05-29 23:45:03

标签: mongodb pymongo

当我更新MongoDB中的文档时,我可以指定是否要返回原始文档或新更新的文档。例如,使用PyMongo,我可以调用:

user = db['users'].find_one_and_update(
    {'email': email},
    {'$set': {'last_login': time.time()}},
    return_document=ReturnDocument.AFTER
)

我也可以使用ReturnDocument.BEFORE

单个 mongo查询是否有办法返回原始值和新值?

3 个答案:

答案 0 :(得分:1)

MongoDB不支持您不幸地尝试做的事情...

  

returnNewDocument |布尔|可选的。为true时,返回更新的   文档而不是原始文档。默认为false。

db.collection.findOneAndUpdate(
   <filter>,
   <update document or aggregation pipeline>, // Changed in MongoDB 4.2
   {
     projection: <document>,
     sort: <document>,
     maxTimeMS: <number>,
     upsert: <boolean>,
     returnNewDocument: <boolean>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ]
   }
)

来自db.collection.findOneAndUpdate()


您可以先将findOneAndUpdate()returnNewDocument = false一起使用,并获取旧值,然后执行常规的findOne(),但两者都在事务块中进行,因此即使有两次调用db,它看起来像是从外部进行的单个操作。

使用PyMongo就像是这样

users = client.db.users
with client.start_session() as session:
    with session.start_transaction():
        oldUser = users.find_one_and_update(
            {'email': email},
            {'$set': {'last_login': time.time()}},
            session=session
        )
        newUser = users.find_one({'email': email}, session=session)
  

return_document默认为ReturnDocument.BEFORE,因此未在find_one_and_update()中明确设置

来自Transactionsclient_session(PyMongo)

答案 1 :(得分:0)

此功能没有本机支持。但是,如果您真的想在数据库端执行这两个命令并返回一个响应-那么您可以编写自定义Javascript函数(使用map_reduce,因为已弃用eval)可以做到这一点。

By this link,您会找到一些示例,这些示例说明如何使用pymongo编写自定义Javascript函数。

答案 2 :(得分:0)

对于类似的用例,我采取了将文档的“历史”修订写入一个单独的数据库,并在主数据库中维护引用记录的关键值的方法。

这可能会或可能不会带来很多后端影响,但是如果不是,这是一种处理数据库版本中记录版本的直接方法。