48JIGEN *Reloaded*

ちょっとだけ読みやすいnode.jsからmongoDBへの接続のコードの書き方と、ハマったところ / (A Bit) Nicer Node.js Code To Read To Connect DB, and other small tips

2011/05/05

※日本語版はこちら
I found many of you are from abroad, so I decided to add English version, not fluent English though.

(A Bit) Nicer Node.js Code To Read To Connect DB

When you install a driver with typing like "npm install mongodb", you will get node-mongodb-native driver installed into your machine.

I tried this driver to connect DB, and finally found a bit nicer(easy to read) node.js code at stackoverflow.com. Just please let me share this.

mongo = require('mongodb');
var db = new mongo.Db('testdb', new mongo.Server('localhost',mongo.Connection.DEFAULT_PORT, {}), {});
var Things;    
    
db.open(function(err, db) {
	db.collection('testcollection', function(err, collection) {
		Things = Things || collection;    
	});
});

Things.find({}, function(err, cursor) {
	cursor.each(function(err, doc) {
		if (doc) sys.log(doc._id);
	});
});

Since node.js is event driven framework and uses Javascript callback frequently, this way inevitably many nesting happens and thus you will get your source code hard to read. However at the source code above, nesting is broken by "Tnings" variable defined outside the nest. This is the point I prefer this code.

Essential Thing You Should Be Careful

If you are a new to node.js like me, mongodb and node-mongodb-native driver, you should be careful with setting db name when you call db initialize function in your code. My mistake was, concretely

var db = new mongo.Db('test', new mongo.Server(...

I should have written like this but by my mistake

var db = new mongo.Db('db', new mongo.Server(...

I did this.

Why I do that was, from mongoDB intereactive shell, you will type like "db.collection_name.find();" which means you will get all db data from current selected database object. According to mongoDB reference, variable "db" is explained as:

The variable that references the current database object / connection. Already defined for you in your instance.

yeah that's it. It does refer database object but "db" doesn't stand for database name.

Since mongoDB is NoSQL and you could store data without specifying database name, it might happen to anybody. Well, it's poor excuse to me, sigh:p I know.

You just type "show dbs" then you can get dbname. Just keep this mind if you are new.

Source Code In github Is Hot

I just would like to say there is many many good source code in github, if you would like to get better in using node.js and mongodb. (e.g. "example" folder of christkv

Other tips I knew by exploring web was for example,

Things.find({}, function(err, cursor) {
	cursor.each(function(err, doc) {
		sys.puts(sys.inspect(doc));
	});
});

this way you can get mongodb find query result with well-formatted style at your terminal. Ok that's all for today.


( * English version)

WebSocketが楽しすぎてこのGWは大体javascriptを触ってた@remoreです。node.jsからmongodbへの接続でハマったところなんかをメモしておきます。

ちょっとだけ読みやすいnode.jsからmongoDBへの接続のコードの書き方

npm install mongodbでドライバをインストールすると、node-mongodb-nativeっていうドライバがインストールされます。

このドライバを使ってDB接続したんですが、Stack Overflowでちょっと読みやすいコードを見つけたので参考までに載せておきます。StackOverflowでアドバイスされている内容とほぼ一緒です。

mongo = require('mongodb');
var db = new mongo.Db('testdb', new mongo.Server('localhost',mongo.Connection.DEFAULT_PORT, {}), {});
var Things;    
    
db.open(function(err, db) {
	db.collection('testcollection', function(err, collection) {
		Things = Things || collection;    
	});
});

Things.find({}, function(err, cursor) {
	cursor.each(function(err, doc) {
		if (doc) sys.log(doc._id);
	});
});

node.jsだとDBへの接続にコールバックを多用するので、コードがネストされまくってみづらくなりがちなんですけど、このコードではcollectionの取得が終わった後一回外の変数に値を渡しているので、ネストが中断されて結果的にちょっとだけ見みやすくなってる(と思う)あたりが気に入ってます。

初めてmongoDBに接続する時にハマったところ

db名の指定でハマりました。具体的には、

var db = new mongo.Db('test', new mongo.Server(...

って書くべきところを、誤って

var db = new mongo.Db('db', new mongo.Server(...

って書いてました。

なんで間違えたかっていうと、mongoDBのインタラクティブシェルからは"db.collection_name.find();"みたいにアクセスしてデータを取り出していたため。シェルのリファレンスによれば、この"db"っていう変数は

この変数は現在接続中のデータベースオブジェクトを参照します。あらかじめ設定されています。

とのこと。データベースオブジェクトを参照しているだけであって、これが固有のDB名を表しているわけではないということに注意してください。僕みたいなうっかりさんはそんなにいないとは思うけど、mongoDBの場合「DBを作成する」っていう手順を踏まずにいきなりデータの保存ができるので、意外とDB名を意識するのを忘れやすいかもしれません。っていう自己擁護。わかってる。

"show dbs"ってシェルから打てば作成されているDBは確認できるので、次からはちゃんと確認してから気をつけてDB接続することにします。

node-mongodb-native関係の情報が少なめ?

node.js用のmongoDBドライバとしては世間ではmongooseの方が有名のようで、node-mongodb-native用の情報、特に実際に動作するコードがあまり見つからなくてデバッグが大変・・なのは実際そうなんですが、そんな時はドライバ開発者のgithubのexamplesフォルダを見てみると良いと思います。

使えるコードがありまくり。例えばfindした結果はsys.inspect()を使って

Things.find({}, function(err, cursor) {
	cursor.each(function(err, doc) {
		sys.puts(sys.inspect(doc));
	});
});

って書くことで綺麗にmonbodbの中身を見れるって知ったりだとか。そういう超使えるノウハウをコードから学んでいけば良いんだと思います。

このエントリーをはてなブックマークに追加

Related Posts

Re: Best Practices in MVC Design with CakePHP

Dockerコンテナ内からホストマシンのルートを取る具体的な方法(あるいは/var/run/docker.sockを晒すことへの注意喚起)

オープンデータの実証用サイトOpen DATA METIを使う

 

about me

@remore is a software engineer, weekend contrabassist, and occasional public speaker. Read more