使用 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 的实例并检索它们:

我正在从 MySQL 切换到 Redis,只是为了制作一个 sql 等价物, 我正在尝试复制这些 sql-where 子句中的任何一个:

我的项目是用 C# 编写的,我已经开始使用 StackExchange.Redis 和 NRediSearch 包。

我不知道如何创建正确的模式索引(通过 redis-cli),也不知道如何使用 NRediSearch 正确存储实体 Client class.

我不需要任何全文或 tokenization/stopwords/etc。 RediSearch 的功能,只是 "simple plain" 文本和整数索引。

我的第一个问题是字符串中存在标点符号(主要是连字符,但在某些情况下也有 双引号)。

我已经根据 TAGNUMERIC 字段类型创建了一个模式:

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/