如何在MongoDB中检索每个文档的最后更新时间?

32

我想知道是否有一种方法可以获得MongoDB集合中数据(即文档)的最后更新/修改时间。更明确地说,我想进行查询以检索所有在特定时间之后更新的文档。

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

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

我正在使用Morphia作为java驱动程序,如果从Morphia有任何可能的方式,请告诉我。


3
可能是与 https://dev59.com/v2DVa4cB1Zd3GeqPhuez 相关的重复问题。 - Ray Toal
4个回答

19

你需要自己捕获最后更新时间。

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

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

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


不,只是在我的DAO框架中。我还没有考虑将我的代码发布给社区。我没有任何问题,只是从未想过这个。 - Ramesh

11

不,MongoDB本身不会存储创建或更新的时间戳。你必须自己完成这个任务(正如你已经发现的那样,如果你使用一个ObjectID _id,那么你就已经得到了创建日期)。


12
并不完全准确。MongoDB确实存储了创建时间,我们可以通过ObjectId("theIdofThedocumen").getTimeStamp()来访问它。 - Amin Mohamed Ajani
1
只有在使用文档创建时生成的ObjectId作为“_id”字段时(您不必这样做),才会如此。 - Thilo
3
当然,你是对的。但我认为最好不要覆盖掉 _id。 - Amin Mohamed Ajani
2
对象创建时间戳,如@AminMohamedAjani所述,ObjectId("507c7f79bcf86cd7994f6c0e").getTimestamp()可以使用,但它是对象创建时间戳。 - Abhijeet
这是一个从ID中检索日期的工具 https://steveridout.com/mongo-object-time/ - Matus

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 属性比你的检索限制更近。


3
你可以进行以下操作。使用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})

如何查找updateOne操作的执行时间? - Jet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接