OnceDB 是基于 Redis 二次开发的全文搜索内存数据库。支持像 SQL 关系数据库和 NoSQL 无模式数据库那样操作数据。
Redis 是当前互联网世界最为流行高性能键值存储内存数据库。Redis 提供比较丰富的数据结构,但直接将 Redis 作为数据库还非常不方便,因此一般作为一种高速缓存工具。
为了让 Redis 能像 MySQL 或 MongoDB 数据库那样适应更多应用场景并提高开发效率。我们基于 Redis 进行了二次开发,添加了全文搜索,多条件查询,分析计算等功能。并通过辅助索引,提高在海量数据下搜索和查询的性能。
OnceDB 通过有序列表(zset)实现辅助索引,大幅提高在复杂条件查询下的搜索性能。OnceDB 并不在底层约束数据模式,数据表、字段、类型、索引等,而通过驱动层来动态定义,改变Schema 定义即可扩展现在有表和字段,从而实现模式的动态定义。
OnceDB 项目地址: http://oncedb.com
快速安装
在 Github 上选择相应操作系统和芯片架构的安装包,解压即可运行。
https://github.com/OnceDoc/OnceDB/releases/
OnceDB 并不改变 Redis 的数据存储结构,与 Redis 3.x 完全兼容,Redis 数据库文件可以直接在 OnceDB 中操作,并再返回 Redis 中使用。您可以直接将原始数据库文件附加在OnceDB中启动。 比如在 Windows 平台下,运行 oncedb-server.exe 即可启动服务。
更新数据
OnceDB 可使用 upsert 或 insert 命令添加数据,并可通过创建辅助索引来提高在大量数据下的搜索性能。OnceDB 通过操作符来自动创建这些索引,命令格式如下:
upsert schema field operator value ...
operator 即为操作符,可使用以下类型:
= 普通字段值,无索引
@ 主键,索引中存放为主键的值。
? 分组索引
* 关键字分组索引,关键字之间使用 ',' 分隔
\ 排序索引,索引的分数权重即为字段的值
示例: 添加一条 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 表中添加了一条数据。“username @ dota” 代表主键字段为 username, 值为 dota。会自动创建一条 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 客户端
使用 node.js 客户端操作数据比通过命令行工具要简单,通过 npm 即可安装:
npm install oncedb
创建实例,连接到本地 oncedb-server:
var oncedb = require('oncedb')()
async/ await 接口
可使用 util.promisify promise 化接口,以支持 async/ await 语法: 比如 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'
}
]
更多内容可参考: OnceDB Node.JS 客户端使用帮助