こおろぎと蛞蝓

―牛ほどの価値もない

nedbでmongooseっぽくデータベースをいじる

同僚に「2時間くらいのあいだ、少人数で使えるしょぼいツイッターみたいなのつくってよ」っていわれてつくってたんだけど、あとで見返したいからツイート(便宜上こう呼ぶ)保存しときたいって言われたので方法を考えてた。

普通にmongoとか使えばいいとは思うんだけど、作業用サーバにmongo入れてなかったし、規模感的にもそこまでする必要性が感じられなかったのでどうにかならんかなーーめんどくさいなーーって感じだった。

jsonデータでやる

最初はjsonファイルで直接やりとりしようとおもった。

var data = require("hoge.json");

みたいな。

でもnode.jsではrequireしたファイルはキャッシュされるので、データを読み込みしようとするたびにrequire("hogehoge").cacheを毎回deleteしないといけなくてださい。

delete require("hoge.json").cache;
var data = require("hoge.json");

ださい。

だからといってfs.readFileJSON.parse/JSON.stringifyでやりくりするのもめんどい。

誰かやってくれてないかなーーめんどくさいなーとおもってぐぐったらちょうどいいのがあった。

nedb (Node Embedded DataBase)

名前からしてなんやお手軽にいけそうな感じがする。 そして、後述するけど乱暴に言えばファイルに読み書きしてるだけだからnpm installする以外に準備がまったくいらない。

素晴らしそうな香り。

nedbつかう

とりあえずinstall

$ npm install nedb

とりあえず使う

var Database = require("nedb");
var db = new Database({filename: "./data/post"});

db.loadDatabase(function (err) {
    db.insert({post: "hogehoge", date: new Date()});
});
  • コンストラクタに渡すfilenameは存在しないファイルだったら新規で作られる
  • 存在してるファイルだったらそいつを読み込んでくれる
  • loadDatabaseでファイル読み込んで、insertにObject渡して更新
  • insertに渡すのをObjectの配列にすれば複数更新
  • insertの第2引数にcallback渡せばinsert後に実行される

取得するときはfindを使う

// 全部取得
db.find().exec(function (err, data) {
    console.log(data);
});

// postが"hogehoge"のやつ
db.find({ post: "hogehoge" }).exec(function (err, data) {
    console.log(data);
});

// dateを降順で上限10件
db.find().sort({ date: -1 }).limit(10).exec(function (err, data) {
    console.log(data);
});

偉そうにつらつら書いてみたけど、お気付きの通りAPImongooseと合わせてきてくれてるので使いやすい。

完全に要求が満たせている。満足という他ない。

githubのスターもいっぱいついてるのに検索しても日本語だと数件しか記事がなくてなんでだろって思った。

ちなみに

$ cat ./data/post
{"post":"hogehoge","date":{"$$date":1414595614292},"_id":"mtgJ3bQjeNeEjEhC"}

みたいな感じで、内部的には結局json形式でデータが保持されてる。

ちょっとだけ実装みたけど、lib/storage.jsっていうそれっぽいファイルでfsmkdirpをexportしてるから、jsonファイルをrequireじゃなくてfsでごにょごにょする方法をとってるっぽい。

あと、githubによるとブラウザでも使えるっていってる。試してないけど。