OnceDB 是基于 Redis 二次开发的全文搜索内存数据库,支持像 SQL 关系数据库和 NoSQL 无模式数据库那样管理数据。
OnceDB 并不改变 Redis 的数据存储结构,与 Redis 3.x 完全兼容,Redis 数据库文件可以直接在 OnceDB 中操作,并再返回 Redis 中使用。
快速安装
在 Github 上选择相应操作系统和芯片架构的安装包,解压即可运行。
https://github.com/OnceDoc/OnceDB/releases/
在 Windows 平台下,运行 oncedb-server.exe 即可启动服务。
更新数据
OnceDB 可使用 upsert 或 insert 命令添加数据。 OnceDB 通过有序列表(zset)实现辅助索引,大幅提高在复杂条件查询下的搜索性能。 OnceDB 通过操作符来自动创建这些索引,命令格式如下:
upsert schema field operator value ...
示例: 添加一条 user 数据,各字段类型如下:
var userInfo = {
username: 'dota' // 主键
, password: '123456' // 普通字段
, title: 'SDEI' // 创建分组索引
, skills: 'java,go,c' // 关键字索引
}
对应的操作符如下:
= 普通字段值,无索引
@ 主键,索引中存放为主键的值。
? 分组索引
* 关键字分组索引,关键字之间使用 ',' 分隔
\ 排序索引,索引的分数权重即为字段的值
您可以选择熟悉的第三方 Redis 客户端连接到 OnceDB,比如在 Redis 默认的 redis-cli 命令行中执行以下命令:
upsert user username @ dota password = 123456 title ? SDEI skills * java,go,c
> OK
这样就成功在 user 表中添加了一条数据。会自动创建 user:dota 的 hash 数据和辅助索引。
辅助索引以 *user 开头,使用 keys * 可查看:
查询数据
可使用 find 指令查询数据,命令格式:
find schema from to field operator value ...
from to 如果是 0 -1 则代表输出所有找到的数据。
索引搜索
如果是是索引字段,可通过操作符从索引中搜索,比如搜索包含 c 关键字的 user 数据,并打印 username 和 password 字段。
find user 0 -1 username = * password = * skills * c
1) (integer) 1
2) "user:dota"
3) "dota"
4) "123456"
5) "java,go,c"
第1行 “(integer) 1” 为符合条件的数据总数。
全文搜索
也可使用字符串搜索查询数据,比如搜索 skills 包含 c 的 user 数据,可使用 "~":
find user 0 -1 username = * password = * skills ~ c
1) (integer) -1
2) "user:dota"
3) "dota"
4) "123456"
5) "java,go,c"
第1行 返回的 -1 表明使用了全文搜索,除了 "~" 字符串匹配外,还支持 “<, >, <=, >=' 等数值比较搜索。 全文搜索性能较差。在有大量数据情况下,推荐使用索引搜索。
Node.JS 客户端
OnceDB 并不在底层约束数据模式,而通过驱动层来动态定义数据表、字段、类型、索引等。可在驱动层实现模式的动态定义。
node.js 客户端,可通过 npm 可安装:
npm install oncedb
然后可创建实例,连接到本地 oncedb-server:
var oncedb = require('oncedb')()
async/ await 接口
可使用 util.promisify 格式化接口,以支持 async/ await 同步语法: 比如 promise 化 oncedb.upsert 更新数据和 oncedb.select 查询数据接口:
const util = require('util')
const oncedb = require('oncedb')()
const update = util.promisify(oncedb.update).bind(oncedb)
const select = util.promisify(oncedb.select).bind(oncedb)
定义 schema 模式
在更新查询数据前,需要先定义 schema 数据模式,指定允许接收哪些字段,设置字段类型,索引等。比如上文的 user 表,可按下面的模式定义:
oncedb.schema('user', {
username : 'id'
, password : ''
, title : 'index'
, skills : 'keywords'
});
更新数据
比如上文的更新和查询,可使用下面的代码, 此处使用同步语法,需要在 async 函数里调用:
(async () => {
// 更新数据
await upsert('user', { username: 'dota', password: '123456', title: 'SDEI', skills: 'java,go,c' })
// 查询数据
let rows = await select('user', { skills: 'c' })
console.log('rows.count', rows.count)
console.log(rows)
})();
输出结果:
rows.count 1
[
{
_key: 'user:dota',
skills: [ 'java', 'go', 'c' ],
username: 'dota',
password: '123456',
title: 'SDEI'
}
]