【问题标题】:Add Timestamp while insertMany() in mongoDB在 mongoDB 中 insertMany() 时添加时间戳
【发布时间】:2020-09-24 04:00:17
【问题描述】:

您好,我是 MySQL 用户,是 mongoDB 的新手。 我从 IOT 设备获取数据如下:

$body={
  "key": "121239",
  "secrete": "Your_Device_Secrete",
  "data": [
    {
      "Temperature":50,
      "Humidity":30,
      "Vibration":100,
      "Time":"2020-1-26 00:00:01"
    },
    {
      "Temperature":55,
      "Humidity":34,
      "Vibration":50,
      "Time":"2020-1-26 00:00:02"
    }
  ]
}

我使用 PHP CodeIgnitor 将其插入到 mongoDB 中,如下所示:

$this->mongo->batch_insert($body["key"],$body["data"]);

数据被插入到名为给定键的集合中,如下所示:

    {
        "Temperature": 50,
        "Humidity": 30,
        "Vibration": 100,
        "Time": "2020-1-26 00:00:01",
        "_id": {
            "$id": "5e330be3f7577f640d2a0922"
        }
    },
    {
        "Temperature": 55,
        "Humidity": 34,
        "Vibration": 50,
        "Time": "2020-1-26 00:00:02",
        "_id": {
            "$id": "5e330be3f7577f640d2a0923"
        }
    }

现在我想为插入的每一行添加时间戳。我希望按如下方式插入数据:

{
        "Temperature": 50,
        "Humidity": 30,
        "Vibration": 100,
        "Time": "2020-1-26 00:00:01",
        "_id": {
            "$id": "5e330be3f7577f640d2a0922"
        },
        timestamp:<CURRUNT TIME>
    },
    {
        "Temperature": 55,
        "Humidity": 34,
        "Vibration": 50,
        "Time": "2020-1-26 00:00:02",
        "_id": {
            "$id": "5e330be3f7577f640d2a0923"
        },
        timestamp:<CURRUNT TIME>
    }

有没有办法让 mongoDB 像 MySQL 一样自动添加当前时间戳?

【问题讨论】:

标签: php mongodb


【解决方案1】:

首先,您不应该将日期/时间值存储为字符串!它只会在以后产生麻烦。更好用

"Time": ISODate("2020-01-26T00:00:02Z")

"Time": new Date("2020-01-26 00:00:02") 也可以工作

那么一般情况下您不需要插入时间戳。每个文档都有一个内部 _id 标识符,其中还包含插入的时间。你可以这样尝试:

db.collection.aggregate([
  {
    $project: {
      timestamp: {
        $toDate: "$_id"
      },
      key: 1,
      secrete: 1,
      data: 1,
      _id: 0
    }
  }
])

结果:

  {
    "data": [
      {
        "Humidity": 30,
        "Temperature": 50,
        "Time": "2018-02-26 01:00:00",
        "Vibration": 100
      },
      {
        "Humidity": 34,
        "Temperature": 55,
        "Time": "2018-02-26 01:00:00",
        "Vibration": 50
      }
    ],
    "key": "121239",
    "secrete": "Your_Device_Secrete",
    "timestamp": ISODate("2018-02-26T00:00:00Z")
  }

您也可以查询它,例如

db.collection.find({
  $expr: {
    $gte: [ {"$toDate": "$_id"}, ISODate("2020-01-03T11:00:00Z") ]
  }
})

但是,如果您想显式插入时间戳,那么只需这样做。

{
"Temperature": 50,
"Humidity": 30,
"Vibration": 100,
"_id": {
    "$id": "5e330be3f7577f640d2a0923"
},
"timestamp": new Date()
}

或者"timestamp": ISODate() 也应该可以工作

另外注意,这个嵌入文档"_id": {"$id": "5e330be3f7577f640d2a0923"} 看起来很奇怪。我认为这是一个错误。该字符串看起来像用于_idObjectId 对象。不知怎的,你刮伤了它。

更新

我真的建议使用正确的数据类型。在 PHP 中,插入可能如下所示:

$mongo->db->collection->insertOne([         
    "timestamp" => new MongoDB\BSON\UTCDateTime(NULL),
    "key" => "121239",
    "secrete" => "Your_Device_Secrete",
    "data" => [
        [
        "Temperature" => 50,
        "Humidity" => 30,
        "Vibration" => 100,
        "Time" => new MongoDB\BSON\UTCDateTime(new DateTime("2020-1-26 00:00:01"))
        ],
        [
        "Temperature" => 55,
        "Humidity" => 34,
        "Vibration" => 50,
        "Time" => new MongoDB\BSON\UTCDateTime(new DateTime("2020-1-26 00:00:02"))
        ]
    ]   
]); 

【讨论】:

  • +1 推荐 ISODate()。很多时候人们使用字符串来表示日期和时间。由于 i18n 和/或格式问题,难以计算。 BTW - MongoDB BSON 类型将时间戳和日期 (ISODate) 区分为两种不同的数据类型。时间戳在内部用于通过 oplog 进行复制。 docs.mongodb.com/manual/reference/bson-types/#timestamps
  • 我的问题是我从 IOT 端以字符串格式的 json 获取数据。我可以将其转换为 php 数组,然后将其传递给 insert_batch 方法以插入 mongoDB。我不想遍历我的数据数组并将所有时间数据转换为时间对象。在 mySQL 中,如果我将字符串数据发送到数据类型为时间戳的字段,默认情况下会将其转换为时间戳。所以我在 mongoDB 中寻找类似的东西。有没有一种方法可以定义在时间字段中发送的所有数据都应该被转换并存储为日期时间对象
  • @barrypicker 是的,但我认为 TO 正在寻找插入当前 Date 值而不是内部 MongoDB 当前 Timestamp 值。 “时间戳”只是“当前日期/时间”的常用短语
  • 是的,谢谢你的帮助,我用你的回答搞定了
【解决方案2】:

在我的 IoT 课程中从 DHT11 传感器读取传感器值时,我也有与您类似的要求。我能够将所有温度和湿度读数插入 MongoDB,但后来在绘制图表时我意识到我也需要时间戳。经过一段时间的研究,我想出了这个查询。但是,它将在数据库中创建一个新集合。 在这里,新的集合名称是 dht11-sensor-readings。

请参阅https://docs.mongodb.com/manual/reference/operator/aggregation/out/ 了解更多信息。

db.collection.aggregate([
    {
        $addFields:{timestamp:{$toDate:"$_id"}
        }
    }, 
    {   $out:"dht11-sensor-readings"
    }
 ])

【讨论】:

    猜你喜欢
    • 2013-06-06
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多