カテゴリー : 2014年 10月

[Mongoose] TypeError: Cannot read property ‘options’ of undefined

Mongoose でスキーマ定義に type: ObjectId としている field にオブジェクト型のデータが入ってると TypeError: Cannot read property ‘options’ of undefined エラーが発生します。

TypeError: Cannot read property 'options' of undefined
  at ObjectId.cast (/u/apps/com/shared/node_modules/mongoose/lib/schema/objectid.js:99:22)
  at /u/apps/com/shared/node_modules/mongoose/lib/document.js:288:29
  at model.Document.$__try (/u/apps/com/shared/node_modules/mongoose/lib/document.js:769:8)
  at init (/u/apps/com/shared/node_modules/mongoose/lib/document.js:287:16)
  at model.Document.init (/u/apps/com/shared/node_modules/mongoose/lib/document.js:246:3)
  at completeOne (/u/apps/com/shared/node_modules/mongoose/lib/query.js:1392:10)
  at Promise.<anonymous> (/u/apps/com/shared/node_modules/mongoose/lib/query.js:1160:11)
  at Promise.<anonymous> (/u/apps/com/shared/node_modules/mongoose/node_modules/mpromise/lib/promise.js:177:8)
  at Promise.EventEmitter.emit (events.js:95:17)
  at Promise.emit (/u/apps/com/shared/node_modules/mongoose/node_modules/mpromise/lib/promise.js:84:38)
  at Promise.fulfill (/u/apps/com/shared/node_modules/mongoose/node_modules/mpromise/lib/promise.js:97:20)
  at Promise.resolve (/u/apps/com/shared/node_modules/mongoose/lib/promise.js:114:23)
  at /u/apps/com/shared/node_modules/mongoose/lib/model.js:2029:23
  at process._tickCallback (node.js:415:13)

再現手順ですが、例えば下記のようなスキーマ定義で、

Article = new Schema
  user:
    type: ObjectId
    ref: 'User'

user filed に ObjectId ではなく { name : ‘hoge’ } のような値を入れて、save するとエラーが発生します。

article = new Article
article.user = { name : 'hoge' } // ObjectId じゃない!
article.save()->

findAndModify などの Mongo DB Native NodeJS Driver を直接呼ぶメソッド findOneAndUpdate メソッドを使ったり、mongo shell で直接データを編集したりするとこういうエンバグさせてしまうので、必要ない限りやめたいですね。


参考情報

findOneAndUpdate – Mongoose API v3.8.18

findAndModify — MongoDB Manual 2.6.4

[Nagios] check_load での load average (ロードアベレージ) のチェックの設定変更

load average が跳ね上がることが増えてきたので、Nagios の check_load コマンドの設定を変更しました。

check_load のデフォルト値

define service{
        use                             generic-service
        host_name                       hoge
        service_description             LOAD
        is_volatile                     0
        check_period                    24x7
        max_check_attempts              3
        normal_check_interval           5
        retry_check_interval            1
        notification_interval           240
        notification_period             24x7
        notification_options            c,r
        check_command                   check_load!1,1,1!2,2,2
        contact_groups                  linux-admins
}

max_check_attempts を 3 回から 2 回に、normal_check_interval を 5 分から 3 分に変更しました。

check_load の設定変更後の値

define service{
        use                             generic-service
        host_name                       hoge
        service_description             LOAD
        max_check_attempts              2
        normal_check_interval           3
        retry_check_interval            1
        check_command                   check_load!1,1,1!2,2,2
}

チェック間隔を短くしたので、サーバが悲鳴をあげる前に対応できるようになるはず。


参考情報

Nagios/プラグイン/check_load – cubic9.com

テンプレートベースオブジェクトデータ設定ファイルオプション

[MongoDB] mongo shell での表示件数は DBQuery.shellBatchSize で設定できる

mongo shell での表示件数はデフォルト 20 件なのですが、これを変更するには DBQuery.shellBatchSize の値を変更すればいいみたいです。

// 表示件数を 500 件にしたい場合
DBQuery.shellBatchSize = 500;

クエリの結果が何件とか予め分かっている場合、その件数を設定すれば一度に結果を全件出力できるので it を入力しなくてよくて便利だったりします。

db.users.find()
...
Type "it" for more
 
// 普段だったら 20 件ごとに it を入力しないといけない

以上です。


参考情報

How to print out more than 20 items (documents) in MongoDB's shell? – Stack Overflow

Getting Started with the mongo Shell — MongoDB Manual 2.6.4

MongoDB の GUI クライアント

MongoDB を mongo shell からでなく GUI クライアントから操作できた方が楽なこともあると聞いて、アプリ入れてみました。

とりあえず、開発環境で使うために Robomongo をインストールしてみました。

Robomongo — shell-centric MongoDB management tool (MongoDB Admin UI)

しばらく、使ってみたいと思います。

[MongoDB] 特定のテキストフィールドが x 文字以上の document を取得する query

MongoDB で特定のテキストフィールドが x 文字以上の document を取得する query をメモ

db.users.find( { name : { $ne: null }, $where: "this.name.length > 5" } )

ポイントは name フィールドに値が存在する場合のみ、$where で長さをチェックしている点です。