25

我想知道是否有办法在 MongoDB 的集合中获取数据(即文档)的最后更新/修改时间。更清楚地说,我想进行查询以检索在特定时间后更新的所有文档。

是否有任何可能的方法可以在 MongoDB 中检索最后修改的时间戳?

注意:对于新创建的文档,我知道我们可以从 objectId 检索时间戳,但对于更新,id 将是相同的。MongoDB 是否将每个文档的最后更新时间存储在任何地方?

我使用 morphia 作为 java 驱动程序,所以如果 morphia 有任何可能的方法,请告诉我。

4

4 回答 4

17

您需要自己捕获上次更新时间。

对于我的应用程序,我保留了一个 AuditTrail 对象,该对象捕获 AuditEvents。这些事件发生在对象的任何插入、更新或删除(删除在我的系统中是虚拟的,只是设置一个标志)。

对于每个 AuditEvent,我都会跟踪日期、经过身份验证的用户、数据库操作以及应用程序填写的描述。这是在 PersistentObject 中实现的,因此对于保存在 Mongo 中的任何对象的任何数据库操作都会自动调用它。

这个实际花费了很少的时间来实现,但提供了获取最后更新时间的能力,以及您可能需要的任何其他信息,以确保 Mongo 中所有内容的安全性和客户支持。

于 2012-12-20T09:37:53.813 回答
7

不,MongoDB 本身不存储创建或更新时间戳。您必须自己执行此操作(并且您已经发现,如果您使用 ObjectID _id 那么您已经获得了创建日期)。

于 2012-12-20T09:18:36.277 回答
5

您可以使用@user1530669 提到的审计跟踪实体(我正在调用我的 delta - 代码已经在 StackOverflow 的某处可用)。

或者您可以简单地保存上次更改时间。我通常使用基本实体来设置它,所有其他实体都对其进行扩展(对于您的特定要求,您可能可以删除它,creationDate因为lastChange对您来说已经足够了):

protected Date creationDate;
protected Date lastChange;

// Getters and setters or final setters which don't do anything,
// if you only want to allow the entity to update the values

@PrePersist
public void prePersist() {
    creationDate = (creationDate == null) ? new Date() : creationDate;
    lastChange = (lastChange == null) ? creationDate : new Date();
}

然后,在您的查询中,您可以添加一个过滤器,以便该lastChange属性比您的检索限制更新。

于 2012-12-20T15:00:12.010 回答
2

您可以执行以下操作。使用MongoDB 4.2+ 版,您现在可以同时执行聚合运算符,例如$toDate从 ObjectId "_id" 中提取时间戳 update

这里我们使用聚合查询$toDate从 MongoDB 的 ObjectId "_id" 字段中提取时间戳,并使用{$replaceRoot: {newRoot: "$$ROOT"}}而不是显式声明来更新文档$set

var collection = "person"

agg_query = [
    {
        "$addFields" : {
            "_last_updated" : {
                "$toDate" : "$_id"
            }
        }
    },
    {
        $replaceRoot: {
            newRoot: "$$ROOT"
        } 
    }
]

db.getCollection(collection).updateMany({}, agg_query, {upsert: true})
于 2020-04-15T11:17:42.453 回答