使用Redis对Redis进行多字段查询Spring

Multi-Field Querying on Redis Using Redis Spring

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

的新手

我目前正在学习 Redis 数据库,并且正在优先开发一项功能,我不得不为该功能使用 Redis。 在下面 challenge/Query 我有。

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

@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 数据库和 return 返回 DurationOfWork 对象。

在这种情况下,我将承受大约 20 小时的负载。每分钟 100000 次调用。

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

***更新了查询

参见 Spring Data Redis - 8.5. Secondary Indexes 和:

  • 8.6。实例查询
  • 8.10。查询和查询方法

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

这意味着当您插入数据时,SDR 将运行 七个命令发送到 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"

使用示例查询:

您想创建一个 repository:

interface OrgWorkRepository extends QueryByExampleExecutor<OrgWork> {
}

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

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 将使用 SINTER and HGETALL:

的组合将其转换为 Redis 命令以获取您的数据
SINTER   …:CorpDetails:CorpDetailsValueHere   …:ContractType:ContractTypeValueHere   ...
HGETALL "OrgWork:d70091b5-0b9a-4c0a-9551-519e61bc9ef3" 
HGETALL ...

这是一个两步过程:

  1. 使用SINTER
  2. 获取二级索引交集中包含的键
  3. 使用 HGETALL
  4. 单独获取 <1> 返回的每个键

假设您拥有高质量的服务器、合理的数据集大小,并且平均查询有些特定,那么对于 Redis,每分钟 100,000 的工作量应该是可以管理的。

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

HGETALL 是 O(N),其中 N 是散列的大小,在您的例子中是 7。

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