MongoDB に入っている 日付文字列 を Date型 へ変換する 方法

0 件のコメント

MongoDB に 文字列 で入れてしまった 日時 を Date オブジェクトへ変換する方法にについてサンプルコードを作成しました。

前提条件

書き換えを行いたいデータは以下のようなものを想定します。 このデータの datetime フィールドを書き換える方法を以下で見ていきます。

データベース
test
コレクション
sample
フィールド
datetime

> use test
> db.sample.find()
{ "_id": ObjectId("xxxxxxxxxxxxxxxxxx"), "datetime": "2017/11/3" }

文字列から日付へ変換するサンプルコード

利用モジュール

サンプルコード最初の2行でわかると思いますが、このサンプルコードでは以下の2モジュールを利用しています。 あらかじめインストールしてから上記サンプルコードを利用してください。

サンプルコード (index.js)

var MongoClient = require("mongodb").MongoClient;
var moment = require("moment");

const CONNECTION_URL = "mongodb://localhost:27017/test";

MongoClient.connect(CONNECTION_URL).then((db) => {
  var collection = db.collection("sample");

  // Get bulk insert operation.
  var bulk = collection.initializeUnorderedBulkOp();

  // Update properties.
  collection.find({ datetime: { $exists: true, $type: 2 } }).forEach((doc) => {
    bulk.find({ _id: doc._id })
      .updateOne({ $set: { datetime: moment(doc.datetime, "YYYY/MM/DD").toDate() } });
  }, (err) => {
    bulk.execute((err, result) => {
      db.close();
      console.log("OK");
    });
  });
});

サンプルコード解説

const CONNECTION_URL = "mongodb://localhost:27017/test";

MongoDBへの接続文字列を設定します。 ここでは localhosttest データベースへ接続しています。 任意に読み替えてください。 ちなみに認証が必要な時は "mongodb://username:password@localhost:27107/database" になります。

  var bulk = collection.initializeUnorderedBulkOp();

データ書き換え量が多いときは Bulk を使ったほうが早いので、 initializeUnorderedBulkOp() で Bulk を生成しています。

  collection.find({ datetime: { $exists: true, $type: 2 } }).forEach((doc) => {

書き換え対象の選定処理です。 フィールド名が datetime で 文字列 の場合に置き換えを行う対象としています。 $type: 2 が 「文字列であること」 を意味しています。 その他の型については $type - MongoDB Manual を参照してください。

      .updateOne({ $set: { datetime: moment(doc.datetime, "YYYY/MM/DD").toDate() } });

日付文字列 を Date型 へ変換する際、必ずしも標準的な文字列になっているとは限らないので、 moment.js を利用してフォーマット指定のパースを行います。 moment をそのまま入れてしまうと余計なデータを保存してしまうので、必ず .toDate() を利用して Date オブジェクトのみ保存するようにします。

以上が MongoDB で 日付文字列 を 日付型 へ変換する方法になります。 参考になりましたでしょうか。 参考までにですが…量があまりに多いときは部分コミットするなどの工夫をしたほうが良いかもしれません。

最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!