【问题标题】:How to get date from object stored in mongodb?如何从存储在 mongodb 中的对象中获取日期?
【发布时间】:2020-12-04 02:38:42
【问题描述】:

我正在制作一个包含聊天和帖子的应用程序,并且在聊天中,我想显示最近帖子的时间。 下面是我的 mongoose 帖子模式的日期部分,以及我的 Mongodb 日期字段的样子。

我正在尝试将日期发送到前端,但不确定如何格式化。我想将其格式化为昨天下午 12:45 或 6 天前等。 非常感谢任何帮助。

Mongoose Schema field for date:

     date: {
        type: Date,
        default: Date.now
      }

Mongodb data field

【问题讨论】:

  • 这个答案可能对您有所帮助。 mongodb-nodejs-how-to-query-isodate-fields
  • Mongo 将始终以有效的日期格式存储它,您必须使用转换器来解析它以在 UI 上显示它。因为它永远是一个相对的问题,所以今天就是明天的昨天。

标签: node.js reactjs mongodb express mongoose


【解决方案1】:

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 小时前。即使日期是“三天”前,仍会显示为两天前。

我希望这个例子能告诉你为什么这种格式没有在任何地方使用,以及它带来的困难。请注意,我什至没有提出像“昨天”这样的时区概念,对于不同的地区来说更具语义化。

在我的选择中,唯一可行的“真正”解决方案是构建一个在代码中执行此操作的自定义函数。请注意,这不是很有趣,因为您必须考虑间隔年、时区、地理区域等事件,但它是可行的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    • 2012-03-18
    • 2011-01-02
    • 2012-03-18
    • 2017-05-05
    • 2017-09-04
    相关资源
    最近更新 更多