OnceDB是基于Redis开发的高性能全文搜索数据库。OnceDB通过辅助索引能极大改善数据查询的性能。像SQL数据库那样,您不用关心索引创建的细节。OnceDB在低端ARM设备上有非常好的性能。
OnceDB使用操作符动态创建索引。OnceDB不改变数据原有的存储结构,您可以使用现有的Redis工具来查看和管理OnceDB中的数据。
数据修改
upsert schema field operator value ...
insert: 插入不存在的数据
update: 更新现有的数据
upsert: 更新或插入数据
操作符
OnceDB使用操作符来创建辅助索引。
@ : 主键
插入一条新数据时,主键 必填
insert article id @ 001 poster = kris
> OK
插入的数据,不能重复
insert article id @ 001 poster = kris
> "ERR article:001 already exist"
使用 insert/upsert 新建的数据,会自动创建主键索引:
keys *
1) *article
2) article:001
*article是主键索引
zrange *article 0 1000 withscores
1) 001
2) 1579691881040
article:001是HASH数据
hgetall article:001
1) id
2) 001
3) poster
4) kris
权重分数是数据更新的时间的整数值。可转化为日期:
new Date(1579691881040).toDateString()
> "Wed Jan 22 2020"
/ : 排序
排序字段
upsert article id @ 001 visit / 10
> 10
upsert article id @ 002 visit / 20
> 10
*article.visit索引会被自动创建:
zrange *article.visit 0 10 withscores
1) 001
2) 10
3) 002
4) 20
权重分数即为字段的值,值必须为数字:
upsert article id @ 001 visit / abc
> ERR not a numeric type abc
? : 分组
按字段分组
upsert article id @ 001 title = test1 poster ? kris
*article.poster:kris索引会被自动创建
zrange *article.poster:kris 0 -1 withscores
1) 001
2) 1579692625593
权重分数是数据更新时间的整数值。
* : 关键字分组
关键字使用","分隔:
upsert article id @ 002 title = "Testing article" keys * python,go,node.js
索引: *article.keys:python, *article.keys:go, *article.keys:node.js 被自动创建。
zrange *article.keys:python 0 -1 withscores
1) 002
2) 1577890088545
^ : 唯一关键字
不可重复字段
upsert user username @ dota email ^ god@like.com
> OK
数据重复验证
upsert user username @ test email ^ god@like.com
> "ERR ^ unique key error *user.email"
*user.email HASH数据被自动创建:
hgetall *user.email
1) god@like.com
2) dota
唯一字段不是索引。
权重分数更新方法
"-" : 不更新存在的分数
默认情况下,更新数据时,索引的权重分数会自动被更新。可使用"*-"选择不更新已有的分数。
例如:
upsert employee id @ 003 keys * js
> OK
zrange *employee.keys:js 0 -1 withscores
1) 003
2) 1577953569271
使用"*-"来更新
upsert employee id @ 003 keys *- go,js
> OK
"go"是新加的关键字, 它的分数与JS不同:
zrange *employee.keys:go 0 -1 withscores
1) 003
2) 1577953576085
zrange *employee.keys:js 0 -1 withscores
1) 003
2) 1577953569271
"js"的分数没有改变。
您可在下面场景中使用:"-"
@- 主键
?- 分组
*- 关键词分组
"=" : 自定义权重分数
使用指定的分数代替默认时间戳作为权重分数。
upsert blog id @=1000 TEST poster ?=2000 kris keys *=3000 go,js
zrange *blog 0 -1 withscores
1) TEST
2) 10000
zrange *blog.poster:kris 0 -1 withscores
1) TEST
2) 2000
zrange *blog.keys:go 0 -1 withscores
1) TEST
2) 3000
@-: 不更新主键分数
upsert blog id @-=3002 TEST
zrange *blog 0 -1 withscores
1) TEST
2) 1000
"@" : 自定义索引名称
操作符中使用@自定义索引名称
upsert group name @@groups oncedb owner ?@groups_owner kris visit /@groups_visits 1
zrange groups 0 -1 withscores
1) oncedb
2) 1578031816226
zrange groups_owner:kris 0 -1 withscores
1) oncedb
2) 1578031816226
zrange groups_visits 0 -1 withscores
1) oncedb
2) 1
数据删除
remove schema @ id field operator ...
OnceDB does not store index definitions and indexes needs to be pointed out manually when deleting
OnceDB不存储索引定义,删除时需要手动指出哪些字段含有索引。
用ID删除数据
upsert people id @ 001
> ok
remove people @ 001
> 1
删除数据和索引
你创建了一条含有索引的数据
upsert people id @ 001 role ? DEV groups * "sun,earth" age / 20
> ok
这样删除
remove people @ 001 role ? groups * age /
> 1
删除自定义索引
upsert article id @article 001 poster ?@auser kris keys *@akeys go,js ctime /@actime 20200101
> ok
remove article @article 001 poster ?@auser keys *@akeys ctime /@actime
> 1
数据搜索
find schema from to field operator value ...
使用FIND指令进行查询
创建测试数据
upsert issue id @ 1 summary = "This is issue 1" creator ? dota keys * go,node.js ctime / 20200101 email ^ go@1.cn
upsert issue id @ 2 summary = "This is issue 2" creator ? like keys * c,node.js ctime / 20200102 email ^ go@2.cn
upsert issue id @ 3 summary = "This is issue 3" creator ? dota keys * c,node.js ctime / 20200103 email ^ go@3.cn
upsert issue id @ 4 summary = "This is issue 4" creator ? dota keys * go,c,node.js ctime / 20200104 email ^ go@4.cn
指定查询范围
查询"ISSUE"的前两年数据,并显示summary, creator, keys 字段
find issue 0 1 summary = * creator = * keys = *
1) "4" # 4 means that there are 4 data in the "issue".
2) "issue:1" # Hash key name
3) "This is issue 1"
4) "dota"
5) "go,node.js"
6) "issue:2"
7) "This is issue 2"
8) "like"
9) "c,node.js"
如果你通过索引查询,第一个返回的数字是数据总数,而不是返回的数据数量。
降序
第一个参数为负数,则代表使用降序。
find issue -1 -2 summary = * keys = *
1) "4"
2) "issue:4"
3) "This is issue 4"
4) "go,c,node.js"
5) "issue:3"
6) "This is issue 3"
7) "c,node.js"
-1是倒数第一个,0代表正数第一个,以倒序输出全部元素:
find issue -1 0 summary = * keys = *
1) 4
2) issue:4
3) This is issue 4
4) go,c,node.js
5) issue:3
6) This is issue 3
7) c,node.js
8) issue:2
9) This is issue 2
10) c,node.js
11) issue:1
12) This is issue 1
13) go,node.js
全文搜索
使用 "=" 精确匹配或 "~" 部分匹配。
find issue 0 -1 id = 1 keys ~ go
1) "-1"
2) "issue:1"
3) "1"
4) "go,node.js"
使用全文搜索,第一条数据会始终返回-1.
通过主键
选择主键和summary字段
find issue 0 1 id @ 2 summary = *
1) "-1"
2) "issue:2"
3) "2"
通过唯一字段
选择唯一字段
find issue 0 1 email ^ go@3.cn summary = *
1) "-1"
2) "issue:3"
3) "go@3.cn"
4) "This is issue 3"
"@": 分数范围
使用 @score 指定分数范围
find schema @min @max field operator value ...
示例:
find issue @20200102 @20200103 ctime / * summary = *
1) "2"
2) "issue:2"
3) "20200102"
4) "This is issue 2"
5) "issue:3"
6) "20200103"
7) "This is issue 3"
选择分数中的范围
find issue 1@20200102 1@20200103 ctime / * summary = *
1) "2"
2) "issue:3"
3) "20200103"
4) "This is issue 3"
通过多个索引
find issue 0 10 creator ? dota keys * go ctime / *
1) "2"
2) "issue:1"
3) "dota"
4) "go,node.js"
5) "20200101"
6) "issue:4"
7) "dota"
8) "go,c,node.js"
9) "20200104"
"+": 指定使用哪个字段的分数权重
find issue 0@20200102 10@20200105 creator ? dota keys * go ctime /+ *
1) "1"
2) "issue:4"
3) "dota"
4) "go,c,node.js"
5) "20200104"
"-": 指定不使用哪个字段的分数
find issue 0@20200102 10@20200105 creator ?- dota keys *- go ctime / *
1) "1"
2) "issue:4"
3) "dota"
4) "go,c,node.js"
5) "20200104"
"=>": 输出到索引
将搜索结果ID保存到有序索引中
find schema=>[index] from to field operator value ...
临时索引
如果没有指定索引名称,会自动生成临时索引
find issue=> 0@20200102 10@20200105 creator ?- dota keys *- go ctime / *
> "*issue.1583844132294743"
zrange *issue.1583844132294743 0 -1 withscores
1) "4"
2) "20200104"
临时索引一小时后会被删除
指定索引名称
指定索引的名称,索引永久有效
find issue=>issue_dota_go 0@20200102 10@20200105 creator ?- dota keys *- go ctime / *
> "issue_dota_go"
不生成索引
只查询一个条件,会返回已经存在的索引
find issue=>issue_dota_go 0 -1 creator ? dota
> "*issue.creator:dota"
倒序 (desc)
from 为负数, 则倒序输出
find issue -1 0 ctime / *
1) 4
2) issue:4
3) 20200104
4) issue:3
5) 20200103
6) issue:2
7) 20200102
8) issue:1
9) 20200101
find issue -1@20200102 0@20200104 ctime / *
1) 3
2) issue:4
3) 20200104
4) issue:3
5) 20200103
6) issue:2
7) 20200102