【问题标题】:StackExchange Redis Search on CollectionStackExchange Redis 集合搜索
【发布时间】:2020-02-15 15:02:57
【问题描述】:

我们正在考虑使用托管在 Azure 中的 Redis。使用 StackExchange nuget,我们的第一个用例是搜索我们的客户群。这最初是大约 10,000 名客户,但会随着时间的推移而增长。

客户将是一个特定的搜索模型,如下所示:

    {
     "Id": 123,
     "Name": "Bob Smith",
     "Age": 72,
     "Postcode": "AB123EF",
     "Email": "bobsmith@anon.com",
     "Telephones": [
        "07710123456", 
        "01453123456"
      ]
    }

我的理解是你应该避免将大的 blob 对象输入到 Redis 中,因此将列表存储为一个对象并不是一个好主意。因此,我们使用 List* 函数将每个项目存储在一个键下并序列化数据。

最初的工作看起来像这样:

    var tasks = new List<Task>();

    foreach (var customer in customers)
    {
     tasks.Add(db.ListLeftPushAsync(_key, JsonConvert.SerializeObject(customer)));
    }

    await Task.WhenAll(tasks).ConfigureAwait(true);

这一切都如我们预期的那样工作,我确信有一些优化,但看起来还可以。

这基本上给我们留下了查询信息的问题。我知道 Redis 将所有内容都存储为字符串,但我不明白如何搜索列表,因为它是 Redis 对象而不是字符串。所以我们不能使用ListRange(_key).Where(c =&gt; c.Contains("Bob")) 为例。

如果我们的方法在这方面有误,或者我只是缺少某种方法,请告诉我。

【问题讨论】:

  • 您考虑过使用 RediSearch 吗?

标签: azure redis stackexchange.redis azure-redis-cache


【解决方案1】:

我完全同意@GuyKorland所说的应该使用像RediSearch这样的成熟产品,而不是实现基于redis的自定义搜索引擎。

不过,我还是很高兴就我对redis的了解,简单介绍一下如何利用redis的数据结构实现一个简单的搜索引擎。

首先,如何将客户数据(如示例客户)存储到 redis 中。要知道,redis 是内存上的 K-V 数据库,因此您可以将对象或 json 数据平面存储为 redis Hash 结构,其键使用唯一的 Id 和前缀,如下所示。

CUSTOM#123 => 
  Id => 123
  Name => Bob Smith
  Age => 72,
  Postcode => AB123EF
  Email => bobsmith@anon.com
  Telephones#0 => 07710123456
  Telephones#1 => 01453123456

其次,使用redis的ListSorted Set结构为对象类的所有属性建立索引,如下所示。

例如,将List 用于NameAge 属性。这个想法是使用前缀NAMEName 之类的对象的Bob 值与# 符号连接起来构建redis 键并将Id 值存储为redis List 元素。

\\ To build `NAME` index for all objects contains `Bob`, `Smith` and `Bob Smith` in the `Name` propertory
NAME#Bob => 123, ... 
NAME#Smith => 123, ...
NAME#Bob Smith => 123, ...
\\ Do the same operation above to build `AGE` index
AGE#72 => 123, ...

最后,您可以在前缀为NAME#的redis键中搜索Bob,使用命令GET NAME#Bob获取客户Id的列表,或者使用命令keys NAME#Bob*获取客户@987654343的列表@fuzzily,那么您可以继续获取这些客户数据,其中包含 Name 属性和 Bob 值。如果要对客户Id的列表进行排序,则应使用Sorted Set而不是ListId列表的结果进行排序。

我还是建议你使用基于redis的成熟产品,比如RediSearch,它会帮助你快速实现你的需求。

【讨论】:

  • 感谢您的回复。 azure 实现不支持开箱即用的 Redisearch,因此如果将它托管在那里,我们必须沿着 docker 路线走。但是,另一种选择是将其托管在我们自己的架构中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-12
  • 2017-08-01
  • 2016-02-12
  • 2017-05-06
  • 2019-04-05
  • 2018-03-22
  • 2022-06-17
相关资源
最近更新 更多