使用Redis Spring在Redis上进行多字段查询

U C*_*U C 4 java response-time redis spring-boot

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

我目前正在学习 Redis 数据库,并且正在优先开发一个功能,我不得不使用 Redis 来实现此功能。下面是我面临的挑战/查询。

现在我们有一个 DataModel 如下:

@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; 

}
Run Code Online (Sandbox Code Playgroud)
public interface OrgWorkRepository extends CrudRepository<HoopCalendar, String> {

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

}
Run Code Online (Sandbox Code Playgroud)

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

在这种情况下,我将有大约的负载。每分钟 100000 个呼叫。

请告诉我这是否是正确的方法以及一些关于缩短响应时间的建议。

***更新了查询

Leo*_*llo 8

请参阅Spring Data Redis - 8.5。二级索引和:

\n\n
    \n
  • 8.6。举例查询
  • \n
  • 8.10。查询和查询方法
  • \n
\n\n

该注释@Indexed指示 Spring Data Redis (SDR) 创建一个二级索引作为集合索引哈希字段。

\n\n

这意味着当您插入数据时,SDR 将向 Redis 运行七个命令:

\n\n
HMSET "OrgWork:19315449-cda2-4f5c-b696-9cb8018fa1f9" "_class" "OrgWork" \n    "id" "19315449-cda2-4f5c-b696-9cb8018fa1f9" \n    "CorpDetails" "CorpDetailsValueHere" "ContractType" "ContractTypeValueHere" \n    ... "Country" "Costa Rica"\nSADD  "OrgWork" "19315449-cda2-4f5c-b696-9cb8018fa1f9"                           \nSADD  "OrgWork:CorpDetails:CorpDetailsValueHere" "19315449-cda2-4f5c-b696-9cb8018fa1f9"\nSADD  "OrgWork:ContractType:ContractTypeValueHere" "19315449-cda2-4f5c-b696-9cb8018fa1f9"\n...\nSADD  "OrgWork:Country:Costa Rica" "19315449-cda2-4f5c-b696-9cb8018fa1f9"\n
Run Code Online (Sandbox Code Playgroud)\n\n

使用示例查询:

\n\n

您想要创建一个存储库

\n\n
interface OrgWorkRepository extends QueryByExampleExecutor<OrgWork> {\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后实现查询,如下面的示例服务所示:

\n\n
class OrgWorkService {\n\n  @Autowired OrgWorkRepository orgWorkRepository;\n\n  List<OrgWork> findOrgWorks(OrgWork probe) {\n    return orgWorkRepository.findAll(Example.of(probe));\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

并用作:

\n\n
OrgWork orgWorkExample = new OrgWork();                          \norgWorkExample.setCorpDetails("CorpDetailsValueHere"); \norgWorkExample.setContractType("ContractTypeValueHere");\n...\nList<OrgWork> results = orgWorkService.findOrgWorks(orgWorkExample);\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
SINTER   \xe2\x80\xa6:CorpDetails:CorpDetailsValueHere   \xe2\x80\xa6:ContractType:ContractTypeValueHere   ...\nHGETALL "OrgWork:d70091b5-0b9a-4c0a-9551-519e61bc9ef3" \nHGETALL ...\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是一个两步过程:

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

假设您拥有优质服务器、合理的数据集大小,并且查询平均而言有些特定,则 Redis 应该可以管理每分钟 100,000 个工作负载。

\n\n

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

\n\n

HGETALL是 O(N),其中 N 是哈希的大小,在您的情况下为 7。

\n\n

与往常一样,建议您进行一些基准测试来测试是否获得所需的性能并根据需要进行调整。

\n

  • 只有代码的风格,取决于如何构建查询。我想你已经有了一件,想展示另一件。我发现 QBE 更面向对象,CrudRepository 上的自动推导有点长参数的味道;另外,如果重命名字段,则需要重命名该函数,我发现那里存在可维护性风险,不确定在这种情况下是否会收到编译错误或警告或什么也没有。品味问题。在幕后,两者都应该收到发送到 Redis 的相同命令并表现出相同的性能 (2认同)