在Electron中使用NeDB保存数据

目录

最近一个使用 Electron 构建的应用程序需要保存用户设置的数据,直接使用本地文件保存设置不容易操作,正好发现一些 JavaScript 实现的数据库,包括 PouchDB 和 NeDB 等。 Windows 下载 Electron 中使用 PouchDB 有问题,所以尝试使用 NeDB。

NeDB 参照 MongoDB 设计,如果对 MongoDB 比较熟悉,上手很容易。下面只介绍简单的使用方法,详细文档请参考

https://github.com/louischatriot/nedb

创建数据库

NeDB 支持内存数据库或持久化数据库,应用程序中为了保存用户设置数据,选择以文件形式保存的持久化数据库。 下面的代码会在当前目录创建一个空的 data.db 文件,并自动加载数据库。

const Datastore = require('nedb');
let data_db = new Datastore({
    filename: 'data.db',
    autoload: true
});

data_db 对象的内容如下:

插入文档

类似 MongoDB,将数据表中的一个记录称为文档。

let doc = {
    id: 1,
    name: 'perillaroc'
};
data_db.insert(doc, function(err, new_doc){
    "use strict";
   console.log(err, new_doc);
});

回调函数中的变量如下图所示:

NeDB 会自动为每条文档添加唯一的 _id 字段,文档会保存到数据文件 data.db 中,如下所示:

{"id":1,"name":"perillaroc","_id":"3wpPvbnmrrHvPhER"}

添加另外两个数据后,数据文件如下所示:

{"id":1,"name":"perillaroc","_id":"3wpPvbnmrrHvPhER"}
{"id":2,"name":"lily","_id":"nesAU4EGnB98fb5C"}
{"id":3,"name":"lucy","_id":"3jNUU4FH6RhG7es0"}

查询文档

使用 find 查找所有满足条件的文档,使用 findOne 查找第一个满足条件的文档。

可以使用操作如,例如:

  • 比较操作符:例如 $lt $lte $gt $gte $in $nin $ne
  • 逻辑操作符:例如 $or $and $not $where

可以使用正则表达式,有两种方式:

  • 使用 javascript 的正则表达式
  • 使用 $regex 操作符

cursor API 用于排序和分页

使用 projections 配置输出结果。

基本查询

data_db.find({id: 1}, function(err, docs){
   console.log(err, docs);
});

回调函数中的参数变量如下图所示:

计数

使用 count 统计文档数,例如统计数据库中所有文档的个数:

data_db.count({}, function(err, count){
   console.log(err, count);
});

回调函数参数变量如下图所示:

更新文档

使用 update 更新文档

data_db.update(
    {name:'lily'},
    {$set: {name: 'anna'}},
    {},
    function(err, numAffected, affectedDocuments, upsert
){
    console.log(err, numAffected, affectedDocuments, upsert);
});

回调函数的变量参数如下图所示:

刚修改后,NeDB尚未进行压缩,修改的条目被添加在数据文件的末尾,文件内容如下:

{"id":3,"name":"lucy","_id":"3jNUU4FH6RhG7es0"}
{"id":1,"name":"perillaroc","_id":"3wpPvbnmrrHvPhER"}
{"id":2,"name":"lily","_id":"nesAU4EGnB98fb5C"}
{"id":2,"name":"anna","_id":"nesAU4EGnB98fb5C"}

进行压缩后(例如再次载入数据库),NeDB 会处理冲突的条目,保存最新的数据,文件内容如下:

{"id":3,"name":"lucy","\_id":"3jNUU4FH6RhG7es0"}
{"id":1,"name":"perillaroc","\_id":"3wpPvbnmrrHvPhER"}
{"id":2,"name":"anna","_id":"nesAU4EGnB98fb5C"}

删除文档

使用 remove 删除文档。

data_db.remove({id: 2}, {}, function(err, numRemoved){
    console.log(err, numRemoved);
});

回调函数中参数变量如下图所示:

刚删除时,数据库会将删除操作记录到数据文件末尾,文件内容如下:

{"id":3,"name":"lucy","_id":"3jNUU4FH6RhG7es0"}
{"id":1,"name":"perillaroc","_id":"3wpPvbnmrrHvPhER"}
{"id":2,"name":"anna","_id":"nesAU4EGnB98fb5C"}
{"$$deleted":true,"_id":"nesAU4EGnB98fb5C"}

数据库压缩后,会将待删除的条目删除,文件内容如下:

{"id":3,"name":"lucy","_id":"3jNUU4FH6RhG7es0"}
{"id":1,"name":"perillaroc","_id":"3wpPvbnmrrHvPhER"}

索引

NeDB 还支持索引,对下面的文档建立索引。

{"id":3,"name":"lucy","_id":"3jNUU4FH6RhG7es0"}
{"id":1,"name":"perillaroc","_id":"3wpPvbnmrrHvPhER"}
{"id":2,"name":"anna","_id":"3tYdZN2G1YK86Isq"}

为id字段创建唯一索引:

data_db.ensureIndex({fieldName: 'id', unique: true}, function(err){
    console.log(err);
});

创建索引后的数据文件如下:

{"id":3,"name":"lucy","_id":"3jNUU4FH6RhG7es0"}
{"id":2,"name":"anna","_id":"3tYdZN2G1YK86Isq"}
{"id":1,"name":"perillaroc","_id":"3wpPvbnmrrHvPhER"}
{"$$indexCreated":{"fieldName":"id","unique":true,"sparse":false}}

因为索引是同步创建的,最好在应用开头建立索引。

参考

NeDB 项目