索引数据修改和查询帮助文档
OnceDB by gh_newghost on 1580296998047


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