Node.js と Mongoose で Mongoose ドキュメントをプレーンオブジェクトに変換する
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