カテゴリー : MongoDB

[MongoDB] MongoError: Runner error: Overflow sort stage buffered data usage of x bytes exceeds internal limit of 33554432 bytes

Express (Node.js) + Mongoose (MongoDB) なアプリケーションで下記のような MongoError が発生しました。

[ERROR] default - { [MongoError: Runner error: Overflow sort stage buffered data usage of 33555427 bytes exceeds internal limit of 33554432 bytes] name: 'MongoError' }
MongoError: Runner error: Overflow sort stage buffered data usage of 33555427 bytes exceeds internal limit of 33554432 bytes
  at Object.toError (/u/apps/com/shared/node_modules/mongoose/node_modules/mongodb/lib/mongodb/utils.js:114:11)
  at /u/apps/com/shared/node_modules/mongoose/node_modules/mongodb/lib/mongodb/cursor.js:689:54
  at Cursor.close (/u/apps/com/shared/node_modules/mongoose/node_modules/mongodb/lib/mongodb/cursor.js:972:5)
  at commandHandler (/u/apps/com/shared/node_modules/mongoose/node_modules/mongodb/lib/mongodb/cursor.js:689:21)
  at /u/apps/com/shared/node_modules/mongoose/node_modules/mongodb/lib/mongodb/db.js:1847:9
  at Server.Base._callHandler (/u/apps/com/shared/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/base.js:445:41)
  at /u/apps/com/shared/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:478:18
  at [object Object].MongoReply.parseBody (/u/apps/com/shared/node_modules/mongoose/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:68:5)
  at [object Object].<anonymous> (/u/apps/com/shared/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:436:20)
  at [object Object].EventEmitter.emit (events.js:95:17)
  at [object Object].<anonymous> (/u/apps/com/shared/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:201:13)
  at [object Object].EventEmitter.emit (events.js:98:17)
  at Socket.<anonymous> (/u/apps/com/shared/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection.js:439:22)
  at Socket.EventEmitter.emit (events.js:95:17)
  at Socket.<anonymous> (_stream_readable.js:746:14)
  at Socket.EventEmitter.emit (events.js:92:17)
  at emitReadable_ (_stream_readable.js:408:10)
  at emitReadable (_stream_readable.js:404:5)
  at readableAddChunk (_stream_readable.js:165:9)
  at Socket.Readable.push (_stream_readable.js:127:10)
  at TCP.onread (net.js:528:21)

sort に指定している field に index を張ってないのが原因でした。

Mongoose の schema 定義に下記のような感じで index 張れば対応完了です。

var User = new Schema({
  created_at: {
    type: Date,
    index: 1
  }
});
 
// or
 
User.index({
  created_at: 1
});

MongoDB に直接 index 張る場合は ensureIndex 使いましょう。

db.users.ensureIndex( { created_at : 1 } )

以上です。

[MongoDB] 改行文字を含む field の値をGoogle スプレッドシートでインポートできる形式で出力する

MongoDB で、改行文字を含む field の値を Google スプレッドシートでインポートできる形式で出力する方法をメモ。

区切り文字には , (カンマ)を使い、改行文字を含むフィールドを ” (ダブルクオーテーション) で囲みます。

下記の例だと、 detail フィールドが改行文字を含みます。

db.products.find( { detail : regExp } ).forEach(function(p){
  print(p._id.valueOf() + ',"' + p.detail + '"');
});

あとは、スクリプトを実行して、実行結果をファイルに出力して、

mongo --quiet mydb script.js > example.csv

Google スプレッドシートにて、「区切り文字:自動的に検出する」で問題なくインポートできるはずです。

google-spreadsheet-import

以上です。

[MongoDB] クエリ結果を標準出力させてファイルに保存する方法

MongoDB で、クエリ結果を標準出力させてファイルに保存するコマンドをメモ。

mongo --quiet dbname ./export_users.js > users.tsv

–quiet オプションを付けると、バージョン表示などの余計な情報が出力されなくなります。

ちなみに、export_users.js は下記のような mongo script です。

var users = db.users.find();
 
users.forEach(function(user) {
  if (user) {
    print(user._id + '\t' + user.name + '\t' + user.email);
  }
});

以上です。

[MongoDB] Port を変えて2台起動する方法 (Mac / Homebrew)

MongoDB を Port を変えて2台起動する手順 on Mac with Homebrew をメモ。

MongoDBをHomebrewでインストールする方法はこちら

mongodb の設定(1台目:ベース)

% cat /usr/local/etc/mongod.conf 
# Store data in /usr/local/var/mongodb instead of the default /data/db
dbpath = /usr/local/var/mongodb
 
# Append logs to /usr/local/var/log/mongodb/mongo.log
logpath = /usr/local/var/log/mongodb/mongo.log
logappend = true
 
# Only accept local connections
bind_ip = 127.0.0.1

デフォルトは 27017 port で起動しているので、2台目は 27018 port で起動させるように設定していきます。

% mkdir /usr/local/var/mongodb_27018
% cp /usr/local/etc/mongod.conf /usr/local/etc/mongod_27018.conf

mongod_27018.conf を下記のような感じに編集します。

※ dbpath, logpath を編集して、port がデフォルトだと 27017 で重複するので 27018 に変更してます。

% cat /usr/local/etc/mongod_27018.conf
# Store data in /usr/local/var/mongodb instead of the default /data/db
dbpath = /usr/local/var/mongodb_27018
 
# Append logs to /usr/local/var/log/mongodb/mongo.log
logpath = /usr/local/var/log/mongodb/mongo_27018.log
logappend = true
 
# Only accept local connections
bind_ip = 127.0.0.1
 
# Default port: 27017
port = 27018

mongod を起動します。

% mongod run --config /usr/local/etc/mongod_27018.conf &

mongod が別portで2台起動していることを確認します。

% lsof -i | grep mongod
mongod      365 bakorer    9u  IPv4 0xd006e2ded5999795      0t0  TCP localhost:28017 (LISTEN)
mongod      365 bakorer   10u  IPv4 0xd006e2deda2a3f7d      0t0  TCP localhost:27017 (LISTEN)
mongod    61419 bakorer    9u  IPv4 0xd006e2dee3ff4795      0t0  TCP localhost:28018 (LISTEN)
mongod    61419 bakorer   10u  IPv4 0xd006e2dee39db795      0t0  TCP localhost:27018 (LISTEN)

以上です。

[MongoDB] 配列フィールドの要素の存在チェック

mongodb で、配列のフィールドに要素が存在するかチェックする条件をメモ。

db.users.find({'friends.0': {$exists: true}})

たまに書くと、「あれ?どう書くんだっけ?」ってなるのですよね。


参考情報

In MongoDB, how do I find documents where array size is greater than 1? – Stack Overflow