NeDBのデータファイルをCLIから操作する

Node.jsなどからローカルファイルを簡易的なデータベースとして利用できるNeDBですが、ちょっとデータを編集するのに毎回コードを書くのも面倒。そこでCLIから利用できる「nedb-repl」を使うと非常に楽ちんに操作できます。 github.com

インストール

npmで一発で入ります。

$ npm install -g nedb-repl

今回は1.2.2が入りました。

$ nedb --version
NeDB v1.8.0 - REPL v1.2.2

基本的な使い方

起動と終了

NeDBのデータファイルのパスを指定して起動します。

$ nedb file.nedb

NeDB v1.8.0 - REPL v1.2.2
Enter .help for usage hints.
Connected to file.nedb datastore.

nedb> 

ファイル名を指定せずに起動した場合、すべてのデータはメモリ上に保存されるためnedbを終了すると消えて無くなります。ちょっとしたテストをしたい場合などに利用します。意図せずこのモードで起動してしまった場合は.open ファイルのパスでデータファイルを開くことができます。

$ nedb

NeDB v1.8.0 - REPL v1.2.2
Enter .help for usage hints.
Connected to in-memory only datastore.
Use .open FILENAME to reopen on a persistent datastore.

nedb> 

終了する時は.exitと打つだけ。たまに「quit」とどっちか分からなくなるのでエイリアスか何かが欲しいw

nedb> .exit
Bye!

コマンド一覧

.helpでnedbで利用できるコマンド一覧を確認できます。最初にドットを付ける記法はSQLiteを思い出しますね。

nedb> .help
.break    Sometimes you get stuck, this gets you out
.clear    Break, and also clear the local context
.editor   Enter editor mode
.exit     Exit the repl
.help     Print this help message
.load     Load JS from a file into the REPL session
.open     Open file to persist data
.save     Save all evaluated commands in this REPL session to a file

ファイルを切り替える

別のデータファイルを開きたい場合は.openに続いて開きたいファイルのパスを指定します。bashzshのようにタブキーで補完するようあ機能はないのでどこかにメモしてコピペするのが楽ですね。

nedb> .open file2.nedb
Opened file file2.nedb

現在開いているファイルを確認する

nedb> db.filename
file2.nedb

挿入 - CREATE

単一のドキュメントを挿入する場合は、連想配列db.insert()に渡します。

nedb> db.insert({name:"apple", price:100})
{"name":"apple","price":100,"_id":"QoETaXbAxo8n4OKr"}

複数のドキュメントの場合は連想配列の配列を渡します。

nedb> db.insert([ {name:"banana", price:80}, {name:"remon", price:100} ])
{"name":"banana","price":80,"_id":"cYIteDzQ8POWWttu"},
{"name":"remon","price":100,"_id":"S87fkb25zHGQwB2q"}

参照 - READ

射影

全件を取り出したい時は条件を指定せず単純にdb.find()を実行します。

nedb> db.find()
{"name":"apple","price":100,"_id":"QoETaXbAxo8n4OKr"},
{"name":"remon","price":100,"_id":"S87fkb25zHGQwB2q"},
{"name":"banana","price":80,"_id":"cYIteDzQ8POWWttu"}

特定の列を指定して出したい場合、いわゆる「射影」を行う場合は第2引数で指定します。1で表示、0で非表示になり_idは意図的に0を指定しない場合は常時出力されます。

nedb> db.find({}, {name:1, _id:0})
{"name":"remon"},
{"name":"banana"},
{"name":"apple"}

検索

第1引数に条件を記入することで、完全一致での絞り込みが行えます。

nedb> db.find({price:80})
{"name":"banana","price":80,"_id":"cYIteDzQ8POWWttu"}

正規表現を利用すれば部分一致での検索も可能です。

nedb> db.find({name:/nana$/})
{"name":"banana","price":80,"_id":"cYIteDzQ8POWWttu"}

比較演算子を利用した検索もできます。以下の例の$gteは「以上」を意味します。

nedb> db.find({price:{"$gte":90}}, {_id:0})
{"name":"remon","price":100},
{"name":"apple","price":100}
比較演算子 意味
$lt 未満 ( < )
$lte 以下 ( <= )
$gt を超える ( > )
$gte 以上 ( >= )

その他にもNeDBと同様の使い方ができます。

ソート

並び替えはdb.find.sort()で行います。第1引数に並び替えを行いたいフィールドを指定します。1で昇順、-1で降順になります。

nedb> db.find({}, {_id:0}).sort({price:1})
{"name":"banana","price":80},
{"name":"remon","price":100},
{"name":"apple","price":100}

nedb> db.find({}, {name:1, price:1, _id:0}).sort({price:-1})
{"name":"remon","price":100},
{"name":"apple","price":100},
{"name":"banana","price":80}

出力件数を指定する

limit()に取り出したい件数を指定します。findの後に書いても良いのですが、通常はsort()で並び替えた後の方が意図したデータを取り出しやすいですね。

nedb> db.find({}, {_id:0}).sort({price:1}).limit(2)
{"name":"banana","price":80},
{"name":"remon","price":100}

スキップ

skip()で先頭から指定した件数をスキップできます。limit()と同時に使うことでページングが可能です。

nedb> db.find({}, {_id:0}).sort({price:1})
{"name":"banana","price":80},
{"name":"remon","price":100},
{"name":"apple","price":100}

nedb> db.find({}, {_id:0}).sort({price:1}).skip(1)
{"name":"remon","price":100},
{"name":"apple","price":100}

更新 - UPDATE

更新はupdate()で行います。第1引数に検索条件、第2引数に更新したいデータを指定します。

nedb> db.update({name:"banana"}, {$set:{price:200}})
1

nedb> db.find({name:"banana"}, {_id:0})
{"name":"banana","price":200}

複数のドキュメントを更新

update()の第3引数でオプションmultiでtrueを指定します。

nedb> db.update({price:100}, {$set:{price:200}}, {multi:true})
2

nedb> db.find({}, {_id:0})
{"name":"apple","price":200},
{"name":"banana","price":80},
{"name":"remon","price":200}

削除 - DELETE

削除はremove()です。第1引数に検索条件を指定します。

nedb> db.remove({name:"banana"})
1

nedb> db.find({name:"banana"})
[]

複数のドキュメントを削除

検索条件を指定しないか、複数のドキュメントが該当するような条件を指定しても、通常は1度に1つしか消してくれません。

nedb> db.remove()
Thrown: TypeError: Cannot read property 'multi' of undefined

もし複数のドキュメントを一度に削除したい場合は第2引数にオプションmultiを指定する必要があります。デフォルトではfalseです。

nedb> db.remove({}, {multi:true})
3

nedb> db.find()
[]

その他

検索結果をカウント

count()の第1引数に検索条件を指定すると該当するドキュメント数をカウントできます。検索条件未指定の場合は全件が対象です。

nedb> db.count()
3

nedb> db.count({price:80})
1

nedb> db.count({price:{$gt:80}})
2

該当するドキュメントが存在しない場合は0が返ります。

nedb> db.count({name:"melon"})
0

注意

NeDBも今回ご紹介したnedb-replも更新が止まって何年も経過しています。あくまで既存システムの運用で使う場合に用いてください。これから新たにコードを書く場合は別のライブラリを利用する方が良いでしょうね。

楽に書けるので気に入っていたので残念です(;´∀`)

参考ページ