使用 Redis Spring 在 Redis 上进行多字段查询 [英] Multi-Field Querying on Redis Using Redis Spring

查看:159
本文介绍了使用 Redis Spring 在 Redis 上进行多字段查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这将是一个非常基本的问题,因为我是 Spring-Redis 的新手

this will be a very baic question since im new to Spring-Redis

我目前正在学习 Redis 数据库,我正在研究一个优先功能,我不得不使用 Redis 来实现这个功能.下面是我遇到的挑战/查询.

Im currently in the process of learning about Redis database and I'm working on a feature on priority, im compelled to Use Redis for this feature. Below in the challenge/Query im having.

现在我们有一个如下的数据模型:

Right now we have a DataModel as below:

@RedisHash("Org_Work")
public class OrgWork {

   private @Id @Indexed UUID id;
   private @Indexed String CorpDetails;
   private @Indexed String ContractType;
   private @Indexed String ContractAssigned;
   private @Indexed String State;
   private @Indexed String Country; 

}

public interface OrgWorkRepository extends CrudRepository<HoopCalendar, String> {

List<OrgWork> findByCorpDetailsAndContractTypeAndStateAndCountry(String CorpDetails, String ContractType, String ContractAssigned, String State, String Country);

}

我们正在开发一个 API 来查询上述数据模型,其中前端将向我们发送 CorpDetails、ContractType、ContractAssigned、State 和 Country 字段,我们必须针对 Redis 数据库查询这些字段并返回 DurationOfWork 对象.

we are developing an API to query on the above Datamodel where the front-end will send us CorpDetails ,ContractType, ContractAssigned, State and Country fields and we have to query these against the Redis Database and return back the DurationOfWork object.

在这种情况下,我将有大约负载.每分钟 100000 次调用.

In this case I will be having a load of approx. 100000 calls per minute.

请让我知道这是否是正确的方法以及一些关于改善响应时间的建议.

Please let me know on if this is the right way and some suggestions on improving response time.

***更新查询

推荐答案

参见 Spring Data Redis - 8.5.二级索引和:

  • 8.6.示例查询
  • 8.10.查询和查询方法

注释 @Indexed 指示 Spring Data Redis (SDR) 创建一个二级索引作为 设置 来索引散列的字段.

The annotation @Indexed instructs Spring Data Redis (SDR) to create a secondary indexed as a set to index the field of the hash.

这意味着当你插入数据时,SDR 会向 Redis 运行 7 个命令:

This means when you insert data, SDR will run seven commands to Redis:

HMSET "OrgWork:19315449-cda2-4f5c-b696-9cb8018fa1f9" "_class" "OrgWork" 
    "id" "19315449-cda2-4f5c-b696-9cb8018fa1f9" 
    "CorpDetails" "CorpDetailsValueHere" "ContractType" "ContractTypeValueHere" 
    ... "Country" "Costa Rica"
SADD  "OrgWork" "19315449-cda2-4f5c-b696-9cb8018fa1f9"                           
SADD  "OrgWork:CorpDetails:CorpDetailsValueHere" "19315449-cda2-4f5c-b696-9cb8018fa1f9"
SADD  "OrgWork:ContractType:ContractTypeValueHere" "19315449-cda2-4f5c-b696-9cb8018fa1f9"
...
SADD  "OrgWork:Country:Costa Rica" "19315449-cda2-4f5c-b696-9cb8018fa1f9"

使用示例查询:

您想创建一个 存储库:

interface OrgWorkRepository extends QueryByExampleExecutor<OrgWork> {
}

然后按照下面的示例服务实现查询:

And then implement the query as in the example service below:

class OrgWorkService {

  @Autowired OrgWorkRepository orgWorkRepository;

  List<OrgWork> findOrgWorks(OrgWork probe) {
    return orgWorkRepository.findAll(Example.of(probe));
  }
}

并用作:

OrgWork orgWorkExample = new OrgWork();                          
orgWorkExample.setCorpDetails("CorpDetailsValueHere"); 
orgWorkExample.setContractType("ContractTypeValueHere");
...
List<OrgWork> results = orgWorkService.findOrgWorks(orgWorkExample);

在幕后,SDR 将使用 的组合将其转换为 Redis 命令以获取您的数据SINTERHGETALL:

Behind the scenes, SDR will take care of converting this to Redis commands to get your data, using a combination of SINTER and HGETALL:

SINTER   …:CorpDetails:CorpDetailsValueHere   …:ContractType:ContractTypeValueHere   ...
HGETALL "OrgWork:d70091b5-0b9a-4c0a-9551-519e61bc9ef3" 
HGETALL ...

这是一个两步过程:

  1. 使用SINTER
  2. 获取二级索引交集中包含的键
  3. 使用 HGETALL
  4. 分别获取 <1> 返回的每个键
  1. Fetch keys contained in the intersection of secondary indexes, using SINTER
  2. Fetch each key returned by <1> individually, using HGETALL

对于 Redis 来说,每分钟 100,000 次的工作负载应该是可以管理的,前提是您拥有高质量的服务器、合理的数据集大小,并且查询的平均水平有些特定.

A workload of 100,000 per minute should be manageable for Redis assuming you have a quality server, a reasonable dataset size, and the queries are somewhat specific in average.

SINTER 的时间复杂度为 O(N*M) 最坏情况,其中 N 是最小集合的基数,M 是集合的数量.您的查询中的每个维度都有一组.

SINTER has a time complexity of O(N*M) worst-case where N is the cardinality of the smallest set and M is the number of sets. You have one set for every dimension on your query.

HGETALL 是 O(N),其中 N 是散列的大小,在您的情况下为 7.

HGETALL is O(N) where N is the size of the hash, 7 in your case.

一如既往,建议您进行一些基准测试以测试您是否获得了所需的性能并在需要时进行调整.

As always, it is recommended you do some benchmarking to test if you're getting the desired performance and adjust if needed.

这篇关于使用 Redis Spring 在 Redis 上进行多字段查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆