NeDB基础使用

@seald-io/nedb 基础使用文档

NeDB 是为"小数据、低并发"场景设计的,数据量在 5~10 万条、并发写入在每秒几百次以内,它完全可以胜任。超出这个范围,请考虑 SQLite 或 MongoDB 等更专业的方案。适合 Node.js 小型项目、Electron、uniapp 等。

包:@seald-io/nedb(社区维护版本,原 nedb 不再更新)

简介

@seald-io/nedb 是 NeDB 的持续维护分支,轻量级嵌入式NoSQL数据库,完全使用JavaScript编写,不需要独立数据库服务。 特性:

  • 文档型数据库,类似MongoDB API
  • 持久化存储(文件) / 内存模式
  • 支持索引、增删改查、排序、分页
  • 异步API,同时支持回调和Promise

适用场景:小型Node脚本、桌面端Electron、本地存储类应用;不适合高并发大数据场景。

安装

npm install @seald-io/nedb

导入

const Datastore = require('@seald-io/nedb')

创建/加载数据库

// 方式一:纯内存数据库(无需加载)
const db = new Datastore()

// 方式二:持久化数据库(手动加载)
const db = new Datastore({ filename: 'path/to/datafile' })
await db.loadDatabaseAsync()

// 方式三:持久化数据库(自动加载)
const db = new Datastore({ filename: 'path/to/datafile', autoload: true }) // 可以立即执行命令

插入文档

// 单条插入
const doc = {
  hello: 'world',
  n: 5,
  today: new Date(),
  nedbIsAwesome: true,
  notthere: null,
  notToBeSaved: undefined,  // undefined 不会被保存
  fruits: ['apple', 'orange', 'pear'],
  infos: { name: '@seald-io/nedb' }
}

const newDoc = await db.insertAsync(doc)
// newDoc 是插入后的文档,包含自动生成的 _id

// 批量插入(原子操作)
const newDocs = await db.insertAsync([{ a: 5 }, { a: 42 }])

查找文档

基础查询

// 查找所有 system 为 'solar' 的文档
const docs = await db.findAsync({ system: 'solar' })

// 正则匹配
const docs = await db.findAsync({ planet: /ar/ })

// 多个条件
const docs = await db.findAsync({ system: 'solar', inhabited: true })

// 点号访问嵌套字段
const docs = await db.findAsync({ 'humans.genders': 2 })

// 查找单个文档
const doc = await db.findOneAsync({ _id: 'id1' })

// 查找全部
const docs = await db.findAsync({})

比较操作符

// $lt 小于
const docs = await db.findAsync({ value: { $lt: 10 } })

// $lte 小于等于
const docs = await db.findAsync({ value: { $lte: 10 } })

// $gt 大于
const docs = await db.findAsync({ value: { $gt: 10 } })

// $gte 大于等于
const docs = await db.findAsync({ value: { $gte: 10 } })

// $in 在列表中
const docs = await db.findAsync({ planet: { $in: ['Earth', 'Mars'] } })

// $nin 不在列表中
const docs = await db.findAsync({ planet: { $nin: ['Earth', 'Mars'] } })

// $ne 不等于
const docs = await db.findAsync({ planet: { $ne: 'Earth' } })

// $exists 字段是否存在
const docs = await db.findAsync({ satellites: { $exists: true } })

// $regex 正则匹配
const docs = await db.findAsync({ planet: { $regex: /ar$/i } })

逻辑操作符

// $or 或
const docs = await db.findAsync({ $or: [{ planet: 'Earth' }, { planet: 'Mars' }] })

// $and 与
const docs = await db.findAsync({ $and: [{ planet: 'Earth' }, { inhabited: true }] })

// $not 取反
const docs = await db.findAsync({ $not: { planet: 'Earth' } })

// $where 自定义函数
const docs = await db.findAsync({ $where: function () { return this.age >= 18 && this.age <= 60 } })

数组操作

// 精确匹配数组
const docs = await db.findAsync({ satellites: ['Phobos', 'Deimos'] })

// $size 匹配数组长度
const docs = await db.findAsync({ satellites: { $size: 2 } })

// $elemMatch 匹配数组元素
const docs = await db.findAsync({
  completeData: {
    planets: { $elemMatch: { name: 'Earth', number: 3 } }
  }
})

排序和分页

// 排序:1 升序,-1 降序
const docs = await db.findAsync({}).sort({ planet: 1 }).skip(1).limit(2)

// 多字段排序
const docs = await db.findAsync({}).sort({ firstField: 1, secondField: -1 })

投影(字段筛选)

// 只返回指定字段
const docs = await db.findAsync({ planet: 'Mars' }, { planet: 1, system: 1 })

// 排除 _id
const docs = await db.findAsync({ planet: 'Mars' }, { planet: 1, system: 1, _id: 0 })

// 排除指定字段
const docs = await db.findAsync({ planet: 'Mars' }, { planet: 0, system: 0, _id: 0 })

// 链式写法
const docs = await db.findAsync({ planet: 'Mars' }).projection({ planet: 1, system: 1 })

计数

// 条件计数
const count = await db.countAsync({ system: 'solar' })

// 全部计数
const count = await db.countAsync({})

更新文档

// 替换整个文档
const { numAffected } = await db.updateAsync({ planet: 'Jupiter' }, { planet: 'Pluton' }, {})

// $set 设置字段
const { numAffected } = await db.updateAsync(
  { system: 'solar' },
  { $set: { system: 'solar system' } },
  { multi: true }
)

// $unset 删除字段
await db.updateAsync({ planet: 'Mars' }, { $unset: { planet: true } }, {})

// $inc 递增
await db.updateAsync({ _id: 'id1' }, { $inc: { value: 1 } }, {})

// $inc 递减
await db.updateAsync({ _id: 'id1' }, { $inc: { value: -5 } }, {})

// $push 向数组添加元素
await db.updateAsync({ _id: 'id6' }, { $push: { fruits: 'banana' } }, {})

// $pop 移除数组末尾元素(1)
await db.updateAsync({ _id: 'id6' }, { $pop: { fruits: 1 } }, {})

// $pop 移除数组开头元素(-1)
await db.updateAsync({ _id: 'id6' }, { $pop: { fruits: -1 } }, {})

// $addToSet 去重添加
await db.updateAsync({ _id: 'id6' }, { $addToSet: { fruits: 'apple' } }, {})

// $pull 移除匹配值
await db.updateAsync({ _id: 'id6' }, { $pull: { fruits: 'apple' } }, {})

// $min 仅在新值更小时更新
await db.updateAsync({ _id: 'id1' }, { $min: { value: 2 } }, {})

// $max 仅在新值更大时更新
await db.updateAsync({ _id: 'id1' }, { $max: { value: 10 } }, {})

// upsert 存在则更新,不存在则插入
const { numAffected, affectedDocuments, upsert } = await db.updateAsync(
  { planet: 'Pluton' },
  { planet: 'Pluton', inhabited: false },
  { upsert: true }
)

删除文档

// 删除单个文档
const { numRemoved } = await db.removeAsync({ _id: 'id2' }, {})

// 删除多个文档
const { numRemoved } = await db.removeAsync({ system: 'solar' }, { multi: true })

// 删除所有文档
const { numRemoved } = await db.removeAsync({}, { multi: true })

删除数据库

await db.dropDatabaseAsync()

索引

// 创建普通索引
await db.ensureIndexAsync({ fieldName: 'somefield' })

// 创建唯一索引
await db.ensureIndexAsync({ fieldName: 'somefield', unique: true })

// 创建稀疏唯一索引
await db.ensureIndexAsync({ fieldName: 'somefield', unique: true, sparse: true })

// 复合索引
await db.ensureIndexAsync({ fieldName: ['field1', 'field2'] })

// TTL 索引(3600秒后自动过期删除)
await db.ensureIndexAsync({ fieldName: 'createdAt', expireAfterSeconds: 3600 })

// 删除索引
await db.removeIndexAsync('somefield')

完整示例

const Datastore = require('@seald-io/nedb')

// 创建内存数据库
const db = new Datastore()

// 插入
await db.insertAsync({ name: 'Alice', age: 25, city: 'Shanghai', tags: ['dev', 'design'] })

// 查询
const result = await db.findOneAsync({ name: 'Alice' })

// 更新
await db.updateAsync({ name: 'Alice' }, { $set: { age: 26 }, $push: { tags: 'manager' } }, {})

// 删除
await db.removeAsync({ name: 'Alice' }, {})

浏览器使用

<script src="nedb.min.js"></script>
<script>
  var db = new Nedb();  // 内存数据库
  db.insert({ planet: 'Earth' }, function (err) {
    db.find({}, function (err, docs) {
      console.log(docs);
    });
  });
</script>

特性总结

特性 说明
API 风格 MongoDB 子集,同时支持 Callback 和 Promise(Async 后缀)
存储方式 内存存储 / 文件持久化
数据类型 String、Number、Boolean、Date、null、Array、Object
_id 自动生成 16 位字母数字字符串,不可修改
undefined 不会被保存到数据库
数据压缩 每次加载数据库时自动压缩,也可手动调用 compactDatafileAsync()
对你有帮助?请作者喝杯咖啡~
lauyimou 支付宝 支付宝
lauyimou 微信 微信
0%