Mongo(几乎?世界上没有其他数据库)存储诸如“昨天”或“上周”之类的常量。
像“昨天”这样的概念的问题在于它非常语义化。如果是 00:01 是昨天 2 分钟前?如果答案是肯定的,那么您实际上必须每分钟更新一次数据库,如果您愿意妥协以查看时差,您仍然必须每天都这样做。
我不确定您的实际业务需求是什么让您想要这样做。但我建议您在获取文档时这样做。否则这是不可扩展的。
这是一个关于如何做到这一点的简单示例:
db.collection.aggregate([
{
"$addFields": {
currDay: {
"$dayOfMonth": "$$NOW"
},
dateDay: {
"$dayOfMonth": "$date"
},
dayGap: {
"$divide": [
{
"$subtract": [
"$$NOW",
"$date"
]
},
86400000/**miliseconds in a day*/
]
}
}
},
{
$addFields: {
date: {
"$switch": {
"branches": [
{
"case": {
$and: [
{
$lt: [
"$dayGap",
1
]
},
{
$eq: [
"$dateDay",
"$currDay"
]
}
]
},
"then": "today"
},
{
"case": {
$lt: [
"$dayGap",
2
]
},
"then": "yesterday"
},
{
"case": {
$lt: [
"$dayGap",
1
]
},
"then": "today"
}
],
default: {
"$concat": [
{
"$toString": {
"$round": "$dayGap"
}
},
" days ago"
]
}
}
}
}
}
],
{
allowDiskUse: true
})
MongoPlayground
如您所见,您必须为每个选项手动构建所需的“短语”。你显然可以在代码中做同样的事情,我只是选择显示“Mongoi”的方式,因为我觉得更复杂。
如果您最终选择提前更新数据库,您可以使用与$out 结合使用的同一管道来实现此目的。
最后一点是我作弊了,因为这个聚合只关注毫秒差异(today 字段除外)。意思是如果它是凌晨 1 点,那么 50 小时前。即使日期是“三天”前,仍会显示为两天前。
我希望这个例子能告诉你为什么这种格式没有在任何地方使用,以及它带来的困难。请注意,我什至没有提出像“昨天”这样的时区概念,对于不同的地区来说更具语义化。
在我的选择中,唯一可行的“真正”解决方案是构建一个在代码中执行此操作的自定义函数。请注意,这不是很有趣,因为您必须考虑间隔年、时区、地理区域等事件,但它是可行的。