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.readFile
とJSON.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); });
偉そうにつらつら書いてみたけど、お気付きの通りAPIはmongooseと合わせてきてくれてるので使いやすい。
完全に要求が満たせている。満足という他ない。
githubのスターもいっぱいついてるのに検索しても日本語だと数件しか記事がなくてなんでだろって思った。
ちなみに
$ cat ./data/post {"post":"hogehoge","date":{"$$date":1414595614292},"_id":"mtgJ3bQjeNeEjEhC"}
みたいな感じで、内部的には結局json形式でデータが保持されてる。
ちょっとだけ実装みたけど、lib/storage.jsっていうそれっぽいファイルでfs
とmkdirp
をexportしてるから、jsonファイルをrequireじゃなくてfsでごにょごにょする方法をとってるっぽい。
あと、githubによるとブラウザでも使えるっていってる。試してないけど。