Node.js と Mongoose で Mongoose ドキュメントをプレーンオブジェクトに変換する

2024-04-10

Node.js と Mongoose で Mongoose ドキュメントをプレーンオブジェクトに変換する方法

toObject() メソッドを使用する

Mongoose ドキュメントには toObject() メソッドが用意されており、これを呼び出すと、ドキュメントをプレーンオブジェクトに変換できます。

const mongoose = require('mongoose');

const schema = new mongoose.Schema({
  name: String,
  age: Number
});

const Model = mongoose.model('Model', schema);

const doc = new Model({
  name: 'John Doe',
  age: 30
});

const obj = doc.toObject();

console.log(obj); // { name: 'John Doe', age: 30 }

この方法は、シンプルで使いやすいですが、いくつかの制限があります。

  • _id フィールドは、デフォルトでプレーンオブジェクトに含まれません。

これらの制限を回避するには、options オプションを toObject() メソッドに渡すことができます。

const obj = doc.toObject({
  virtuals: true,
  transform: (_doc, ret) => {
    ret._id = ret._id.toString();
  }
});

console.log(obj); // { _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }

JSON.stringify() メソッドを使用して、Mongoose ドキュメントを JSON 文字列に変換できます。その後、JSON 文字列を JavaScript オブジェクトに解析できます。

const obj = JSON.parse(JSON.stringify(doc));

console.log(obj); // { _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }

この方法は、すべてのフィールドを含めることができ、仮想フィールドも含まれます。ただし、_id フィールドは、デフォルトで文字列に変換されます。

Lodash ライブラリの _.cloneDeep() メソッドを使用して、Mongoose ドキュメントのディープコピーを作成できます。

const _ = require('lodash');

const obj = _.cloneDeep(doc);

console.log(obj); // { _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }

自作の関数を使用する

上記のいずれの方法にも満足できない場合は、自作の関数を使用して、Mongoose ドキュメントをプレーンオブジェクトに変換できます。

function toObject(doc) {
  const obj = {};

  for (const key of Object.keys(doc)) {
    if (key === '_id') {
      obj._id = doc._id.toString();
    } else if (doc.schema.virtuals[key]) {
      obj[key] = doc.get(key);
    } else {
      obj[key] = doc[key];
    }
  }

  return obj;
}

const obj = toObject(doc);

console.log(obj); // { _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }

この方法は、最も柔軟性の高い方法ですが、最も複雑でもあります。

  • シンプルで使いやすい方法が必要であれば、toObject() メソッドを使用するのがおすすめです。
  • すべてのフィールドを含める必要があり、仮想フィールドも含まれる場合は、JSON.stringify() メソッドまたは _.cloneDeep() メソッドを使用するのがおすすめです。
  • より多くの制御が必要であれば、自作の関数を使用するのがおすすめです。



const mongoose = require('mongoose');

const schema = new mongoose.Schema({
  name: String,
  age: Number
});

const Model = mongoose.model('Model', schema);

const doc = new Model({
  name: 'John Doe',
  age: 30
});

// toObject() メソッドを使用する
const obj1 = doc.toObject();

console.log(obj1); // { name: 'John Doe', age: 30 }

// JSON.stringify() メソッドを使用する
const obj2 = JSON.parse(JSON.stringify(doc));

console.log(obj2); // { _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }

// Lodash の _.cloneDeep() メソッドを使用する
const _ = require('lodash');

const obj3 = _.cloneDeep(doc);

console.log(obj3); // { _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }

// 自作の関数を使用する
function toObject(doc) {
  const obj = {};

  for (const key of Object.keys(doc)) {
    if (key === '_id') {
      obj._id = doc._id.toString();
    } else if (doc.schema.virtuals[key]) {
      obj[key] = doc.get(key);
    } else {
      obj[key] = doc[key];
    }
  }

  return obj;
}

const obj4 = toObject(doc);

console.log(obj4); // { _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }

このコードを実行すると、以下の出力が得られます。

{ name: 'John Doe', age: 30 }
{ _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }
{ _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }
{ _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }



Mongoose ドキュメントをプレーンオブジェクトに変換するその他の方法

.lean() メソッドを使用する

Mongoose クエリに .lean() メソッドをチェーンすることで、クエリ結果をプレーンオブジェクトの配列として取得できます。

const docs = await Model.find().lean();

console.log(docs); // [{ _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }]

この方法は、大量のデータを処理する必要がある場合に役立ちます。

const doc = new Model({
  name: 'John Doe',
  age: 30
});

const obj = doc.toObject();

console.log(obj); // { _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }

この方法は、toObject() メソッドのオプションを使用して、変換をカスタマイズできます。

自作の変換ロジックを使用する

function toObject(doc) {
  const obj = {};

  // 独自の変換ロジック

  return obj;
}

const doc = new Model({
  name: 'John Doe',
  age: 30
});

const obj = toObject(doc);

console.log(obj); // { _id: '5f4dcc3b97624a4428b25678', name: 'John Doe', age: 30 }
  • より多くの制御が必要であれば、Mongoose ODM の Document#toObject() メソッドまたは自作の変換ロジックを使用するのがおすすめです。

node.js mongoose


【決定版】Node.js で HTTP リダイレクトをスマートに処理する 3 つの方法とサンプルコード

res. writeHead() と res. end() を使用する最も基本的な方法は、res. writeHead() と res. end() 関数を使用して、ステータスコードと Location ヘッダーを設定する方法です。この例では、/old/path にアクセスすると、ステータスコード 302 (Found) と Location ヘッダーに /new/path を設定し、クライアントを新しい URL にリダイレクトします。...


npm install コマンドを使いこなせ! 依存関係の再インストールをマスターしよう

最も基本的な方法は、npm install コマンドを実行することです。このコマンドは、package. json ファイルに記載されている依存関係をすべてインストールします。このコマンドを実行すると、以下の処理が行われます。package...


Node.js、TypeScript、Mocha.js で発生する「Cannot find module 'ts-node/register'」エラーの解決策

"Cannot find module 'ts-node/register'" エラーは、TypeScript で書かれた Mocha テストを実行しようとした際に発生する一般的なエラーです。これは、TypeScript コードを実行するために必要な ts-node/register モジュールが見つからないことを意味します。...


Node.js ドライバーが適切にインストールされていることを確認

接続情報を確認するまず、接続情報に誤りがないことを確認してください。以下の項目を確認しましょう。ホスト名またはIPアドレス: MariaDBサーバーのホスト名またはIPアドレスが正しいことを確認してください。ポート番号: MariaDBサーバーのデフォルトポートは3306ですが、設定によっては変更されている場合があります。正しいポート番号を使用していることを確認してください。...


【Node.js, ESLint, WebStormユーザー必見】「ESLint: TypeError: this.libOptions.parse is not a function」エラーを根本から解決する方法

解決策は以下の通りです:ESLint を 8.22 以下にダウングレードする:node_modules フォルダと package-lock. json ファイルを削除します。npm install コマンドを実行して、ESLint を再インストールします。...