開発室ブログ

JavaScript mongoDB Node.js

mongoose の find() で取得したオブジェクトが全く編集できない件

こんにちは、開発室の阿部です。

突然ですが、皆さんはドッジボールは好きですか? 小学生のころ、誰もがやったことがあるドッジボールです。 僕はめちゃくちゃドッジボールが好きです。

実言うと、僕は小学生のころドッジボール少年団に所属してました。 小学5年の時には全国大会準優勝するぐらいガチでやってました。 でも自慢しようにもマイナーなんです。。。 今の20代後半ぐらいの人たちが小学生ぐらいの時がドッジボールの全盛期でした。 コロコロコミックで「炎の闘球児 ドッジ弾平」というドッジボールを題材にした漫画(アニメ化もされてます)もありました。

あの大手運送会社「クロネコヤマト」もスポンサーとして付いてたんですよ!

そんな公式で行われるドッジボールは皆さんの想像する、ひたすら避けまくるそれとは別次元です。

これは2015年の全国大会の動画です。  1試合5分の短い中で、”パスは5回まで”などのルールがあり、攻守がすばやく切り替わっていくのでめちゃくちゃ熱いんですよ~。 このカラーコートって呼ばれるカラフルなコートは全国大会の特徴で皆ここでやるのを夢見てたわけです。

ということで、今後飲み会の席とかで「昔スポーツやってた?」みたいな質問に「ドッジボールです!」と答える人がいてもバカにせず、バスケやサッカーとかと同じぐらい熱のあるスポーツと思ってあげてください・・・。 では、本題へ!

Mongoose で取得した値は編集できない?

以前、Node.js + Mongoose でWEBツールを作っていた際、Mongooseで取得した値に対し、処理を加え、新たに情報を付加する。という部分を構築していたのですが全く変化が無い・・・。

// 求めたい結果
[{
  _id: 5b19ea01f3c1661d2c10a537,
  name: 'adidas',
  type: 'sports',
  founder: 'Adolf Adi Dassler',
  add: 'I like this' // 追加されるはずの行
}, {
  _id: 5b19ea90f3c1661d2c10a538,
  name: 'nike',
  type: 'sports',
  founder: 'mark parker',
  add: 'I like this' // 追加されるはずの行
}, {
  _id: 5b19eac6f3c1661d2c10a539,
  name: 'sony',
  type: 'electronics',
  founder: 'Masaru Ibuka & Akio Morita',
  add: 'I like this' // 追加されるはずの行
}, {
  _id: 5b19ec05f3c1661d2c10a53a,
  name: 'panasonic',
  type: 'electronics',
  founder: 'Konosuke Matsushita',
  add: 'I like this' // 追加されるはずの行
}, {
  _id: 5b19ec66f3c1661d2c10a53b,
  name: 'pilot',
  type: 'stationery',
  founder: 'Ryosuke Namiki',
  add: 'I like this' // 追加されるはずの行
}, {
  _id: 5b19eccbf3c1661d2c10a53c,
  name: 'montblanc',
  type: 'stationery',
  founder: 'undefinde',
  add: 'I like this' // 追加されるはずの行
}]

最初にやってみた方法

めちゃくちゃ普通の方法です。


Brands.find({}, (err, result) => {
  if (err) throw err;

  // 全ての行に プロパティを追加する
  result.forEach((row) => {
    row.add = 'I like this.';
  });
});

結果は…

// 全く変わらない、なんぞ・・・
[{
  _id: 5 b19ea01f3c1661d2c10a537,
  name: 'adidas',
  type: 'sports',
  founder: 'Adolf Adi Dassler'
}, {
  _id: 5 b19ea90f3c1661d2c10a538,
  name: 'nike',
  type: 'sports',
  founder: 'mark parker'
}, {
  _id: 5 b19eac6f3c1661d2c10a539,
  name: 'sony',
  type: 'electronics',
  founder: 'Masaru Ibuka & Akio Morita'
}, {
  _id: 5 b19ec05f3c1661d2c10a53a,
  name: 'panasonic',
  type: 'electronics',
  founder: 'Konosuke Matsushita'
}, {
  _id: 5 b19ec66f3c1661d2c10a53b,
  name: 'pilot',
  type: 'stationery',
  founder: 'Ryosuke Namiki'
}, {
  _id: 5 b19eccbf3c1661d2c10a53c,
  name: 'montblanc',
  type: 'stationery',
  founder: 'undefinde'
}]

全く変わりませんね。

解決

以下、回答 https://stackoverflow.com/questions/23943651/mongodb-admin-user-not-authorized

ここの回答に 「MongoDBから取得したものはプレーンなjavascript じゃないから編集できないよ」風なことが書いてあります、なるほど。 そして解決案がこちら

lean() を使ってプレーンなjavascriptを結果として受け取る



Brands.find().lean().exec((error, result) => { 
  result.forEach((row) => { 
    row.like = 'I like this.'; 
  });
  console.log(result);
    
});

すると


[{
  _id: 5 b19ea01f3c1661d2c10a537,
  name: 'adidas',
  type: 'sports',
  founder: 'Adolf Adi Dassler',
  like: 'I like this.'
}, {
  _id: 5 b19ea90f3c1661d2c10a538,
  name: 'nike',
  type: 'sports',
  founder: 'mark parker',
  like: 'I like this.'
}, {
  _id: 5 b19eac6f3c1661d2c10a539,
  name: 'sony',
  type: 'electronics',
  founder: 'Masaru Ibuka & Akio Morita',
  like: 'I like this.'
}, {
  _id: 5 b19ec05f3c1661d2c10a53a,
  name: 'panasonic',
  type: 'electronics',
  founder: 'Konosuke Matsushita',
  like: 'I like this.'
}, {
  _id: 5 b19ec66f3c1661d2c10a53b,
  name: 'pilot',
  type: 'stationery',
  founder: 'Ryosuke Namiki',
  like: 'I like this.'
}, {
  _id: 5 b19eccbf3c1661d2c10a53c,
  name: 'montblanc',
  type: 'stationery',
  founder: 'undefinde',
  like: 'I like this.'
}]

このように無事オブジェクトに新たにプロパティが追加されました。 なので、基本的にはfind().lean()の組み合わせを使ったほうが汎用性が高いですね。

RecentPost