Edited at

NeDB を使ってみた

More than 3 years have passed since last update.


はじめに

Electron を使ってデスクトップアプリを作成しようとしています。ある程度のデータを保存しておいて検索したりしたいので、データベースエンジンを使用したいと思います。

ただし今回は、アプリと別にデータベースエンジンをインストールする必要があるのは避けたいと思いました。

Electron であれば、Web Storage や Indexed DB が使えるけれど、使い勝手がいいとは言えません。

アプリに組込できるタイプのデータベースエンジンを探しました。その中に NeDB がありました。

参考 Node.jsで使えるファイルDB"NeDB"のススメ


NeDB とは

NeDB は、組込型の永続的あるいはインメモリのデータベースで、Node.js 、NW.js 、Electron およびブラウザで動作し、100 % JavaScript でバイナリ依存しません。API は MongoDB のサブセットで、非常に高速です。

公式 louischatriot/nedb: Embedded datastore for node.js


NeDB を使ってみた


  • NeDB 1.8.0


インストールする

Node.js アプリのワークスペースにインストールします。

npm install --save nedb 


データベースを作成する


インメモリのみ(データベース読込不要)

var Datastore = require('nedb');

var db = new Datastore();


永続的なデータストアに手動で読込

var Datastore = require('nedb');

var db = new Datastore({
filename: '◇◇/◆◆.db'
});
db.loadDatabase();
あるいは
db.loadDatabase(function(err){
// コマンドが実行される
});

ファイル名の拡張子は任意です。

ファイルはなければ自動で作成されます。

あれば読込まれます。


永続的なデータストアに自動で読込

var Datastore = require('nedb');

var db = new Datastore({
filename: '◇◇/◆◆.db',
autoload: true
});
// 直ぐにコマンドが発行できる


複数コレクションを作成

var db = {};

db.◆◆ = new Datastore('◇◇/◆◆.db');
db.●● = new Datastore('◇◇/●●.db');
db.◆◆.loadDatabase();
db.●●.loadDatabase();

コレクションごとに読込する必要あります。非同期で実行されます。


ドキュメントを挿入する

MongoDB もそうですが、NoSQL データベースでは、データの構成単位は「レコード」でなく「ドキュメント」なんですね。

var doc = {

○○: ◇◇,
....
};
db.insert(doc);
あるいは
db.insert(doc, function(err, newDoc){
....
});

newDoc は新規挿入されたドキュメント。

_id フィールドが追加されます。これは 16 文字の英数文字列。変更は不可です。

ドキュメントの配列も挿入できます。

var docs = [

{ .... },
{ .... },
];
db.insert(docs, function(err, newDocs){
....
});

newDocs は配列になります。

内容が同一のドキュメントは挿入できません。


ドキュメントを検索する


基本的な問合せ


指定した値と一致するドキュメントを検索

db.find({ ○○: ●● }, function(err, docs){

....
});

docs はドキュメントの配列です。一致するドキュメントがなければ [] になります。


指定した文字列を「含む」ドキュメントを検索

db.find({ ○○: /●●/ }, function(err, docs){

....
});


条件を AND 指定してドキュメントを検索

db.find({ ○○: ●●, ◇◇: ◆◆ }, function(err, docs){

....
});


条件を指定せず全てのドキュメントを検索

db.find({}, function(err, docs){

....
});


指定した値と一致するドキュメントの一つを検索

db.findOne({ ○○: ●● }, function(err, doc){

....
});

doc は一致するドキュメントがなければ null になります。


比較演算


指定した値より小さい

db.find({ ○○: { $lt: ●● } }, function(err, docs){

....


指定した値より小さいか等しい

db.find({ ○○: { $lte: ●● } }, function(err, docs){

....


指定した値より大きい

db.find({ ○○: { $gt: ●● } }, function(err, docs){

....


指定した値より大きいか等しい

db.find({ ○○: { $gte: ●● } }, function(err, docs){

....


指定した値のいずれかと一致する

db.find({ ○○: { $in: [●●, ◆◆] } }, function(err, docs){

....


指定した値と異なる

db.find({ ○○: { $ne: ●● } }, function(err, docs){

....


指定した値のいずれでもない

db.find({ ○○: { $nin: [●●, ◆◆] } }, function(err, docs){

....


指定したフィールドがある

db.find({ ○○: { $exists: true } }, function(err, docs){

....


正規表現を他の条件指定と合わせて使う。例えば

db.find({ ○○: { $regex: /●●/, $nin: [◆◆, ■■] } }, function(err, docs){

....


条件を論理演算


条件を OR 指定

db.find({ $or: [{ ○○: ●● }, { ◇◇: ◆◆ }] }, function(err, docs){

....


条件を NOT 指定

db.find({ $not: { ○○: ●● } }, function(err, docs){

....


関数を使って条件指定

db.find({ $where: function(){ return this.○○ = ●●; } }, function(err, docs){

....


指定を組合せる。例えば

db.find({ $or: [{ ○○: ●● }, { ◇◇: ◆◆ }], □□: ■■ }, function(err, docs){

....


並替など


並替

db.find({ .... }).sort({ ○○: 1 }).exec(function(err, docs){

....


逆順に並替

db.find({ .... }).sort({ ○○: -1 }).exec(function(err, docs){

....


複数フィールドを指定して並替

db.find({ .... }).sort({ ○○: 1, ◇◇: 1 }).exec(function(err, docs){

....


先頭から指定した数だけ

db.find({ .... }).sort({ .... }).limit(●).exec(function(err, docs){

....


ドキュメントのフィールドを指定


指定したフィールドだけ

db.find({ .... }, { ○○: 1, ◇◇: 1 }, function(err, docs){

....


指定したフィールドを除いて

db.find({ .... }, { ○○: 0, ◇◇: 0 }, function(err, docs){

....


MongoDB と非互換の書き方

db.find({ .... }).projection({ ○○: 1, ◇◇: 1 }).exec(function(err, docs){

....


ドキュメントをカウントする


指定した条件に一致するドキュメントをカウント

db.count({ .... }, function(err, count){

....
});


条件を指定せず全てのドキュメントをカウント

db.count({}, function(err, count){

....
});


ドキュメントを更新する


ドキュメントの内容を別のに置換

db.update({ .... }, { ○○: ◆◆ }, { multi: .... }, function(err, numReplaced){

....
});

指定されたフィールドの値が置換えられます。

指定されなかったフィールドは残らないので注意が必要です。

_id は変更されずに保持されます。


既存のフィールドの値を置換

db.update({ .... }, { $set: { ○○: ●● } }, { multi: .... }, function(err, numReplaced){

....
});

指定されたフィールドの値が置換えられます。

指定されなかったフィールドと値は残ります。


フィールドを削除

db.update({ .... }, { $unset: { ○○: true } }, {}, function () {

....
});


ドキュメントあるいはフィールドがあれば更新、なければ挿入

db.update({ .... }, { ○○: ●● }, { upsert: true }, function(err, numReplaced, upsert){

....
});


ドキュメントを削除する


指定した条件のドキュメント一つを削除する

db.remove({ .... }, {}, function(err, numRemoved){

....
});


指定した条件のドキュメント全てを削除する

db.remove({ ... }, { multi: true }, function(err, numRemoved){

....
});


全てのドキュメントを削除する

db.remove({}, { multi: true }, function(err, numRemoved){

....
});


おわりに

API が MongoDB のサブセットなので、新たなリファレンスは要らないとも思ったけれど、自分が MongoDB のコマンドをよく知らないのと、完全な互換ではなさそうなので、整理を兼ねて記事にしておくことにしました。

これでも公式サイトのドキュメントの全部ではありません。自分が使うにはこれだけあれば十分かなと思って書きました。

  • ドキュメントを削除する
  • おわりに