カテゴリー : MongoDB

MongoDB query でタブ文字区切りの文字列を出力させた結果をコピペするとタブ文字が消えることがあるのでファイル出力するのがベスト

本記事でお伝えしたいことはタイトルで完結していますが、先日 MongoDB の Query を書ける営業社員から「Mongo Query の出力結果を Google スプレッドシートに貼り付けると左に列がずれるのでコードレビューしてほしい」と相談されました。

結論としては query 自体には何も問題なく、タブ文字 \t 区切りで文字列を出力すると Mac の Terminal アプリからコピー&ペーストするときに折り返し位置によって \t が消えてしまうことがあるようでした。

ファイル出力すればタブ文字が消えてしまう問題は発生しないので、

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

のような感じでファイルに出力して、これを Google スプレッドシートにインポートすると列がずれることがなくなりました。

もし、似たような問題が発生した方は Terminal アプリからのコピペの部分の挙動を疑ってみると解決するかもしれませんよ。

MongoDB shell で Object を出力するなら printjson() を使おう

MongoDB shell で Object を出力したいなら print() では出力できないので printjson() を使いましょう。

以下、Object を print() と printjson() の実行結果のサンプルを貼っておきます。

> var object = { a : 1 , b : 2 };
 
> print(object);
[object Object]
 
> printjson(object);
{ "a" : 1, "b" : 2 }
 
> printjson(1)
1
> printjson("a")
"a"

ほとんどの場合は printjson() を使うといいかもですね。


参考情報

[MongoDB] field 名の命名規則

MongoDB のドキュメントを確認すると field の命名規則にゆらぎがあるので決めの問題なんでしょうね。

places_id と snake_case で書かれています。

こちらは cancelDate と lowerCamelCase で書かれています。

アプリケーションコードで扱いやすい命名規則に書き方を統一するといいんじゃないでしょうか。

[MongoDB] E11000 duplicate key error index の code 11000 と 11001 の違い

MongoDB version 2.4.5 で unique index による duplicate key error index エラー発生時の error code には 11000 と 11001 があるのですが、その違いについて調べてみました。

事前準備

> db.version()
2.4.5
 
> db.so.drop();
> db.so.insert( { foo: 5 } );
> db.so.ensureIndex( { foo: 1 }, { unique: true } );
> db.so.insert( { foo: 6 } );

新規追加系メソッド insert のケース

db.collection.insert() で duplicate key error index エラーが発生したときは 11000 のエラーコードを返します。

> db.so.insert( { foo: 5 } );
E11000 duplicate key error index: test.so.$foo_1  dup key: { : 5.0 }
 
> db.getPrevError();
{
	"err" : "E11000 duplicate key error index: test.so.$foo_1  dup key: { : 5.0 }",
	"code" : 11000,
	"n" : 0,
	"nPrev" : 1,
	"ok" : 1
}

更新系メソッド update / save のケース

db.collection.update()db.collection.save() などの更新系のメソッドで duplicate key error index エラーが発生したときは 11001 のエラーコードを返します。

このときに紛らわしいのは、エラーメッセージ E11000 duplicate key error index に含まれているエラーコードが 11000 ということです。

> db.so.update( { foo: 6 }, { $set: { foo: 5 } } );
E11000 duplicate key error index: test.so.$foo_1  dup key: { : 5.0 }
 
> db.getPrevError();
{
	"err" : "E11000 duplicate key error index: test.so.$foo_1  dup key: { : 5.0 }",
	"code" : 11001,
	"n" : 0,
	"nPrev" : 1,
	"ok" : 1
}
> var so6 = db.so.findOne( { foo: 6 } )
> so6.foo = 5
5
 
> db.so.save( so6 )
E11000 duplicate key error index: test.so.$foo_1  dup key: { : 5.0 }
 
> db.getPrevError();
{
	"err" : "E11000 duplicate key error index: test.so.$foo_1  dup key: { : 5.0 }",
	"code" : 11001,
	"n" : 0,
	"nPrev" : 1,
	"ok" : 1
}

まとめ

MongoDB version 2.4.5 では、エラーメッセージは E11000 duplicate key error index と同じだけど、エラーコードは 11000 と 11001 の2種類があるバグっぽい処理になっていました。

このため、プログラム上で duplicate key error を処理したいときは if(err.code === 11000 || err.code === 11001) みたいな感じで扱うといいかもしれません。

なお MongoDB version 3.0.2 で試してみたところエラーコードは 11000 に統一されているようでした。

なので、err.code === 11001 だけのコードは MongoBD を upgrade したタイミングで動かなくなってしまうので注意が必要そうです。

> db.version()
3.0.2
 
> db.so.insert( { foo: 5 } );
WriteResult({
	"nInserted" : 0,
	"writeError" : {
		"code" : 11000,
		"errmsg" : "E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 }"
	}
})
 
> db.so.update( { foo: 6 }, { $set: { foo: 5 } } );
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 0,
	"nModified" : 0,
	"writeError" : {
		"code" : 11000,
		"errmsg" : "E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 }"
	}
})
 
> var so6 = db.so.findOne( { foo: 6 } )
> so6.foo = 5
5
> db.so.save( so6 )
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 0,
	"nModified" : 0,
	"writeError" : {
		"code" : 11000,
		"errmsg" : "E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 }"
	}
})

以上です。

参考情報

[MongoDB] データベースファイルが保存されるパス dbpath を確認する

MongoDB のデータベースファイルが保存される dbpath は db.serverCmdLineOpts() の実行結果から確認できます。

dbpath を確認するクエリ

db.serverCmdLineOpts().parsed.dbpath           // MongoDB 2.4 and older
db.serverCmdLineOpts().parsed.storage.dbPath   // MongoDB 2.6+

(例) db.serverCmdLineOpts() の実行結果

dbPath 以外にも config ファイルや systemLog ファイルの出力先なども確認できます。

> db.serverCmdLineOpts()
{
	"argv" : [
		"/usr/local/opt/mongodb/bin/mongod",
		"--config",
		"/usr/local/etc/mongod.conf"
	],
	"parsed" : {
		"config" : "/usr/local/etc/mongod.conf",
		"net" : {
			"bindIp" : "127.0.0.1"
		},
		"storage" : {
			"dbPath" : "/usr/local/var/mongodb"
		},
		"systemLog" : {
			"destination" : "file",
			"logAppend" : true,
			"path" : "/usr/local/var/log/mongodb/mongo.log"
		}
	},
	"ok" : 1
}

以上です。


参考情報