OnceDB:让Redis像sql和mongodb数据库那样全文搜索,多条件查询,分析计算,自动索引海量数据

OnceDB 是基于 Redis 二次开发的全文搜索内存数据库,支持像 SQL 关系数据库和 NoSQL 无模式数据库那样管理数据。

OnceDB 并不改变 Redis 的数据存储结构,与 Redis 3.x 完全兼容,Redis 数据库文件可以直接在 OnceDB 中操作,并再返回 Redis 中使用。

 

Redis 特点

性能强劲

我们一直在开发能够运行在 arm 和 x86 平台上的管理软件。很多 arm 开发板运行在 TF 存储卡中。TF 卡的读写速度其实非常有限,读取、写入速度在 10~30M/s 之间,只有 Redis 这样的内存数据库,才能够在 arm 设备持续向外传送文件时,依然保持非常优异的并发能力,而不会造成 Web 服务不可用。

开发效率

Redis 中存放的只是一些基本的数据结构,只能通过复杂的方法实现数据索引、查询,所以如果只使用 Redis 数据库的话,开发效率非常低。所以一般以其它数据库为主,Redis 作为高性能缓存层来使用。

 

二次开发 Redis

为了充分利用 Redis 优异的性能,并能像 MySQL 或 MongoDB 数据库那样适应更多应用场景并提高开发效率。我们基于 Redis 进行了二次开发,添加了全文搜索,多条件查询,分析计算等功能。并通过辅助索引,提高在海量数据下搜索和查询的性能。该项目命名为 OnceDB, 支持 Windows 和 Linux,

快速安装 OnceDB

在 Github 上选择相应操作系统和芯片架构的安装包,解压即可运行。

https://github.com/OnceDoc/OnceDB/releases/

在 Windows 平台下,运行 oncedb-server.exe 即可启动服务。

OnceDB 辅助索引

OnceDB 通过有序列表( zset )实现辅助索引,大幅提高在复杂查询条件下,搜索海量数据的性能。

OnceDB 可使用 upsert 或 insert 命令添加数据,并通过操作符来自动创建这些索引。

比如添加一条 user:dota 数据,并设置相应索引:

@ 为 username 主键字段
? 为 title 创建分组索引
* 为 skills 创建关键字索引

命令如下

upsert user username @ dota password = 123456 title ? SDEI skills * java,go,c
> OK

然后可使用 find 指令查询数据,如果是是索引字段,可通过操作符从索引中搜索,比如搜索包含 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” 为符合条件的数据总数。如果使用全文搜索,则会返回 -1。

比如全文搜索包含 c 的数据, 可使用 "~" 操作符:

find user 0 -1 username = * password = * skills ~ c
1) (integer) -1
2) "user:dota"
3) "dota"
4) "123456"
5) "java,go,c"

返回的 -1 表明使用了全文搜索,全文搜索支持 “<, >, <=, >=' 等数值比较搜索。

更多指令帮助请参考: OnceDB 数据修改和查询帮助文档

 

OnceDB 驱动客户端( node.js )

OnceDB 并不在底层约束数据模式,而通过驱动层来动态定义数据表、字段、类型、索引等,改变 Schema 定义即可扩展现在有表和字段,从而实现模式的动态定义。

OnceDB 客户端已经发布,可通过 npm 可安装:npm install oncedb

安装完成后可,连接到本地 oncedb-server:

var oncedb = require('oncedb')()

在更新查询数据前,需要先定义 schema 数据模式,指定含有哪些字段,设置字段类型,索引等。比如上文的 user 数据,可定义成如下模式:

oncedb.schema('user', {
    username  : 'id'
  , password  : ''
  , title     : 'index'
  , skills    : 'keywords'
});

然后可以通过 oncedb.upsert 更新数据。

oncedb.upsert('user', { username: 'dota', password: '123456', title: 'SDEI', skills: 'java,go,c' }, function(err) {
  // done
})

然后查询数据,此时会自动根据 schema 中的定义,从相应索引查询数据。

oncedb.select('user', { skills: 'c' }, function(err, rows) {
   console.log('rows.count', rows.count)
   console.log(rows)
})

async / await 同步语法

可使用 util.promisify 格式化接口,将回调改造成 async/ await 同步语法:

const util    = require('util')
const oncedb  = require('oncedb')()

const update  = util.promisify(oncedb.update).bind(oncedb)
const select  = util.promisify(oncedb.select).bind(oncedb)

然后上面的 callback 模式就可改写成顺序模式:

// 更新数据
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'
  }
]

此时可根据 rows.count 来判断是不是启用了索引搜索,如果是 -1,则代表使用了全文搜索。

更多帮助请参考: OnceDB Node.JS 客户端使用帮助

你可能感兴趣的:(OnceDB:让Redis像sql和mongodb数据库那样全文搜索,多条件查询,分析计算,自动索引海量数据)