我需要在Redis中存储简单的实体对象(C#)。 我还需要使用二级索引和精确匹配来搜索它们。在尝试使用Redis natvie数据类型后,我选择尝试RediSearch来完成此任务。
但是我找不到我需要的方式。
我的目标很简单。实体数据结构非常简单。例如,我有一个Device
类,听起来像这样(我省略了大多数不能索引的string / int字段,因此与示例无关)
public class Device
{
public int Id { get; set; } // primary key
public string Name { get; set; } // no indexing on this
public string SerialNumber { get; set; } // this is indexed and unique
public string ServerNode { get; set; } // this is indexed
public int Status { get; set; } // this is indexed, possible values 0..4
public string Info { get; set; } // no indexing on this
}
我需要存储Device
类的实例并检索它们:
SerialNumber
ServerNode
和/或Status
的列表我正在从MySQL切换到Redis,只是为了使它等效于sql, 我正在尝试复制以下任何sql-where子句:
WHERE SerialNumber = 'RK01:"12345678"'
WHERE ServerNode = 'Node-US-01'
WHERE Status BETWEEN 1 AND 3
WHERE ServerNode = 'Node-IT-04' AND Status = 4
我的项目是用C#编写的,我已经开始使用StackExchange.Redis和NRediSearch软件包。
我无法弄清楚如何(通过redis-cli)创建正确的架构索引,也无法理解如何使用NRediSearch Client
类正确存储实体。
我不需要全文本或标记化/停用词/等。 RediSearch的功能,只是“简单纯文本”和整数索引。
我的第一个问题是字符串中是否存在标点符号(主要是连字符,但在某些情况下还包含双引号)。
我已经基于TAG
和NUMERIC
字段类型创建了一个架构:
FT.CREATE Device NOHL NOOFFSETS NOFREQS STOPWORDS 0 SCHEMA Id NUMERIC SORTABLE SerialNumber TAG SORTABLE ServerNode TAG SORTABLE Status NUMERIC SORTABLE
我尝试通过NRediSearch(然后通过redis-cli用于测试目的)添加“文档”:
通过redis-cli:
FT.ADD Device obj:Device:1 1.0 FIELDS Id 1 Name "FoobarDevice" SerialNumber "RK01:\"12345678\"" ServerNode "Node-US-01" Status 1 Info "this and that"
通过NRediSearch
var rsc = new Client("Device", redis_database);
var doc = new Document("obj:Device:1");
doc.Set("Id", 1);
doc.Set("Name", "FoobarDevice");
doc.Set("SerialNumber", "RK01:\"12345678\"");
doc.Set("ServerNode", "Node-US-01");
doc.Set("Status", 1);
doc.Set("Info", "this and that");
rsc.AddDocument(doc);
如果在redis-cli中键入以下任何命令,则会在屏幕上显示正确的设备实体:
> FT.GET Device obj:Device:1
要么
> HGETALL obj:Device:1
现在的问题:我无法对这些索引执行任何查询。 首先,我不清楚命令行上正确的查询语法。这是一些无效的示例:
>FT.SEARCH Device @ServerNode:{Node-US-01}
>FT.SEARCH Device "@ServerNode:{Node-US-01}"
>FT.SEARCH Device @ServerNode:"{Node-US-01}"
>FT.SEARCH Device @ServerNode:{"Node-US-01"}
>FT.SEARCH Device @SerialNumber:{RK01:\"12345678\"}
我收到语法错误或没有结果。
我知道序列号字符串有点奇怪,但是我不能更改其格式。
我应该在文档中存储字符串值的转义版本吗? 与sql类where子句产生相同结果的正确语法是哪一种? 我该如何处理在值本身包含双引号(“)的字段值上进行字符串搜索?
最后但并非最不重要的是,我找不到有关使用NRediSearch Query类和QueryBuilder命名空间的任何澄清示例或文档 (但是,在我了解RediSaerch的“想法”之后,这也许会变得晦涩一些。)
答案 0 :(得分:3)
您对数据建立索引就好了,唯一的问题是您的搜索查询。您的数据包含RediSearch自动标记的字符(例如-
和:
)。为了避免进行tokanization,您需要在查询中对其进行转义。请注意,在使用redis-cli时,必须进行两次转义,以便转义字符(\
)实际上会发送到redis。
使用"
会带来更多问题,您必须在查询和redis-cli中对其进行转义,因此您将需要三个转义符(两个转义字符将被发送到redis,一个转义字符将被发送至redis)。
看起来像这样:
127.0.0.1:6379> FT.SEARCH Device "@ServerNode:{Node\\-US\\-01}"
1) (integer) 1
2) "obj:Device:1"
3) 1) Id
2) "1"
3) Name
4) "FoobarDevice"
5) SerialNumber
6) "RK01:\"12345678\""
7) ServerNode
8) "Node-US-01"
9) Status
10) "1"
11) Info
12) "this and that"
127.0.0.1:6379> FT.SEARCH Device "@SerialNumber:{RK01\\:\\\"12345678\\\"}"
1) (integer) 1
2) "obj:Device:1"
3) 1) Id
2) "1"
3) Name
4) "FoobarDevice"
5) SerialNumber
6) "RK01:\"12345678\""
7) ServerNode
8) "Node-US-01"
9) Status
10) "1"
11) Info
12) "this and that"
您可以在此处阅读有关tokanization和转义的更多信息:https://oss.redislabs.com/redisearch/Escaping.html#the_rules_of_text_field_tokenization