使用 RediSearch 对实体进行简单的字符串和整数索引
Usage of RediSearch for simple string and integer indexing on entities
我需要在 Redis 中存储简单的实体对象 (C#)。
我还需要使用二级索引和精确匹配来搜索它们。在与 Redis natvie 数据类型斗争之后,我选择尝试 RediSearch 来完成这项任务。
但是我找不到如何按照我需要的方式使用它。
我的目标很简单。实体数据结构非常简单。例如,我有一个 Device
class 听起来像这样(我省略了大多数不能被索引的 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
class 的实例并检索它们:
- 个人,
SerialNumber
- 作为
ServerNode
and/or 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
class.
我不需要任何全文或 tokenization/stopwords/etc。 RediSearch 的功能,只是 "simple plain" 文本和整数索引。
我的第一个问题是字符串中存在标点符号(主要是连字符,但在某些情况下也有 双引号)。
我已经根据 TAG
和 NUMERIC
字段类型创建了一个模式:
FT.CREATE Device NOHL NOOFFSETS NOFREQS STOPWORDS 0 SCHEMA Id NUMERIC SORTABLE SerialNumber TAG SORTABLE ServerNode TAG SORTABLE Status NUMERIC SORTABLE
我尝试通过 NRediSearch 添加 "documents"(但也通过 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 查询 class 和 QueryBuilder 命名空间的说明示例或文档
(但在我了解 RediSaerch "thinks" 之后,这可能会变得不那么晦涩难懂)。
您已将数据编入索引,唯一的问题是您的搜索查询。您的数据包含 RediSearch 自动标记化的字符(如 -
和 :
)。为了避免标记化,您需要在查询中转义它们。请注意,当使用 redis-cli 时,您必须进行两次转义,以便转义字符 (\
) 实际上会被发送到 redis。
"
问题更大,您必须在查询和 redis-cli 中对它进行转义,因此您将需要三个转义(两个以便将转义字符发送到 redis,一个在 cli 中对它进行转义).
它看起来像这样:
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"
您可以在此处阅读有关令牌化和转义的更多信息:https://oss.redislabs.com/redisearch/Escaping/
我需要在 Redis 中存储简单的实体对象 (C#)。 我还需要使用二级索引和精确匹配来搜索它们。在与 Redis natvie 数据类型斗争之后,我选择尝试 RediSearch 来完成这项任务。
但是我找不到如何按照我需要的方式使用它。
我的目标很简单。实体数据结构非常简单。例如,我有一个 Device
class 听起来像这样(我省略了大多数不能被索引的 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
class 的实例并检索它们:
- 个人,
SerialNumber
- 作为
ServerNode
and/orStatus
的列表
我正在从 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
class.
我不需要任何全文或 tokenization/stopwords/etc。 RediSearch 的功能,只是 "simple plain" 文本和整数索引。
我的第一个问题是字符串中存在标点符号(主要是连字符,但在某些情况下也有 双引号)。
我已经根据 TAG
和 NUMERIC
字段类型创建了一个模式:
FT.CREATE Device NOHL NOOFFSETS NOFREQS STOPWORDS 0 SCHEMA Id NUMERIC SORTABLE SerialNumber TAG SORTABLE ServerNode TAG SORTABLE Status NUMERIC SORTABLE
我尝试通过 NRediSearch 添加 "documents"(但也通过 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 查询 class 和 QueryBuilder 命名空间的说明示例或文档 (但在我了解 RediSaerch "thinks" 之后,这可能会变得不那么晦涩难懂)。
您已将数据编入索引,唯一的问题是您的搜索查询。您的数据包含 RediSearch 自动标记化的字符(如 -
和 :
)。为了避免标记化,您需要在查询中转义它们。请注意,当使用 redis-cli 时,您必须进行两次转义,以便转义字符 (\
) 实际上会被发送到 redis。
"
问题更大,您必须在查询和 redis-cli 中对它进行转义,因此您将需要三个转义(两个以便将转义字符发送到 redis,一个在 cli 中对它进行转义).
它看起来像这样:
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"
您可以在此处阅读有关令牌化和转义的更多信息:https://oss.redislabs.com/redisearch/Escaping/