Mongodb-根据其他字段值添加额外的字段

时间:2019-09-05 05:54:18

标签: mongodb mongodb-query aggregation-framework

我在db中有以下格式的文档:

{
"_id" : ObjectId("5d6fb50852020c4a182fc773"),
"startTimestamp" : "1567601927157"
}

我要实现的是,使用“ startTimestamp”值创建以下新字段:

  • 日期(格式为“ 04-09-2019”)
  • 小时(例如“ 18”)
  • 月(例如“ 9”)
  • 时间(例如“ 18:28:47”)
  • weekDay(例如“星期三”)

我是否可以查询所有文档并执行上述操作,并最终以以下格式创建相应的文档

{
"startTimestamp" : "1567601927157",
"date" : "04-09-2019",
"hour" : "18",
"month" : "9",
"time" : "18:28:47",
"weekDay" : "Wednesday",
}  

修改:
“ startTimestamp”不是文档中存在的唯一字段,它还有其他字段,如下所示:

 {
 "useCaseStatus" : "In Progress",
"feedbackRequested" : false,
"userFeedback" : null,
"startTimestamp" : "1567669352778"
 }  

通过在上述文档中添加新字段,我不想删除已经存在的字段(因为到目前为止我所获得的所有解决方案都删除了文档中存在的其他字段)。另外,在下面再添加一个预期文档(请注意,小时和月字段为字符串格式,而不是整数):

{
 "useCaseStatus" : "In Progress",
"feedbackRequested" : false,
"userFeedback" : null,
"startTimestamp" : "1567669352778",
"endTimestamp" : null,
"date" : "05-09-2019",
"hour" : "13",
"month" : "9",
"time" : "13:12:32",
"weekDay" : "Thursday"
}

3 个答案:

答案 0 :(得分:3)

您可以使用以下汇总

db.collection.aggregate([
  { "$replaceRoot": {
    "newRoot": {
      "$let": {
        "vars": { "date": { "$toDate": { "$toLong": "$startTimestamp" } } },
        "in": {
          "$mergeObjects": [
            {
              "date": { "$dateToString": { "date": "$$date", "format": "%d-%m-%Y" } },
              "month": { "$toString": { "$month": "$$date" } },
              "hour": { "$toString": { "$hour": "$$date" } },
              "time": { "$dateToString": { "date": "$$date", "format": "%H-%M-%S" } },
              "weekDay": { "$dayOfWeek": "$$date" }
            },
            "$$ROOT"
          ]
        }
      }
    }
  }},
  { "$out": "collectionName" }
])

Output

{
  "date": "04-09-2019",
  "hour": 12,
  "month": 9,
  "startTimestamp": "1567601927157",
  "time": "12-58-47",
  "weekDay": 4
}

答案 1 :(得分:1)

您需要以$toLong$toDate开头来解析您的字符串。然后,您可以使用$dateToParts$dayOfWeek。要将数字转换为字符串,可以使用$switch

db.collection.aggregate([
    {
        $addFields: {
            date: {
                $toDate: {
                    $toLong: "$startTimestamp"
                }
            }
        }
    },
    {
        $addFields: {
            dateParts: { $dateToParts: { date: "$date" } },
            dayOfWeek: { $dayOfWeek: "$date" }
        }
    },
    {
        $project: {
            startTimestamp: 1,
            date: { $dateToString: { date: "$date", format: "%d-%m-%Y" } },
            hour: "$dateParts.hour",
            month: "$dateParts.month",
            time: { $dateToString: { date: "$date", format: "%H:%M:%S" } },
            weekDay: {
                $switch: {
                    branches: [
                        { case: { $eq: [ "$dayOfWeek", 1 ] }, then: "Sunday" },
                        { case: { $eq: [ "$dayOfWeek", 2 ] }, then: "Monday" },
                        { case: { $eq: [ "$dayOfWeek", 3 ] }, then: "Tuesday" },
                        { case: { $eq: [ "$dayOfWeek", 4 ] }, then: "Wednesday" },
                        { case: { $eq: [ "$dayOfWeek", 5 ] }, then: "Thursday" },
                        { case: { $eq: [ "$dayOfWeek", 6 ] }, then: "Friday" }
                    ],
                    default: "Saturday"
                }
            }
        }
    }
])

Mongo Playground

答案 2 :(得分:0)

您需要实现聚合管道并使用可用的日期运算符,但是由于您已将毫秒保存在字符串中,因此我们首先必须将其转换为int,然后再转换为date,然后再从perfrom date运算符中注意到,其中一些将需要时区才能给出准确的结果,给出utc结果

db.collection.aggregate([
  {
    $addFields: {
      longMillis: {
        $toLong: "$startTimestamp"
      }
    }
  },
  {
    $project: {
      startTimestamp: 1,
      "date": {
        "$add": [
          new Date(0),
          "$longMillis"
        ]
      }
    }
  },
  {
    $project: {
      startTimestamp: 1,
      month: {
        $month: "$date"
      },
      day: {
        $switch: {
          branches: [
            {
              case: {
                $eq: [
                  {
                    $dayOfMonth: "$date"
                  },
                  1
                ]
              },
              then: "Sunday"
            },
            {
              case: {
                $eq: [
                  {
                    $dayOfMonth: "$date"
                  },
                  2
                ]
              },
              then: "Monday"
            },
            {
              case: {
                $eq: [
                  {
                    $dayOfMonth: "$date"
                  },
                  3
                ]
              },
              then: "Tuesday"
            },
            {
              case: {
                $eq: [
                  {
                    $dayOfMonth: "$date"
                  },
                  4
                ]
              },
              then: "Wednesday"
            },
            {
              case: {
                $eq: [
                  {
                    $dayOfMonth: "$date"
                  },
                  5
                ]
              },
              then: "Thursday"
            },
            {
              case: {
                $eq: [
                  {
                    $dayOfMonth: "$date"
                  },
                  6
                ]
              },
              then: "Friday"
            },
            {
              case: {
                $eq: [
                  {
                    $dayOfMonth: "$date"
                  },
                  7
                ]
              },
              then: "Saturday"
            },

          ],
          default: 6
        }
      },
      hour: {
        $hour: {
          "date": "$date",
          "timezone": "+05:30"
        }
      },
      date: {
        $dateToString: {
          format: "%d-%m-%Y",
          date: "$date"
        }
      },
      time: {
        $dateToString: {
          format: "%H:%M:%S",
          date: "$date",
          timezone: "+05:30"
        }
      },

    }
  }
])

给出结果:

[
  {
    "date": "04-09-2019",
    "day": "Wednesday",
    "hour": 18,
    "month": 9,
    "startTimestamp": "1567601927157",
    "time": "18:28:47"
  }
]