gemfire - 通过部分键查询 GemFire 区域
问题描述
当 key 是 GemFire Region 中 id1、id2 的组合并且 Region 用 id1 分区时,获取 key 匹配 id1 的所有行的最佳方法是什么。
我们正在考虑的几个选项:
在 id1 上创建另一个索引。如果我们这样做,我们想知道它是否违反所有分区区域?
将数据感知函数和过滤器(id1,null)写入目标特定分区区域。通过使用在本地区域中使用索引
QueryService
?
如果有其他方法可以通过部分键实现查询,请告诉我。
解决方案
好吧,它可以通过在上面的“选项”中使用 #1 和 #2 的组合来实现(最佳)(取决于您的应用程序域对象是否也存储/引用了密钥,如果您使用的是 SD [G] 存储库。
这可能最好通过文档和示例来解释,特别是使用PartitionResolver
接口Javadoc。
假设您的“复合”键实现如下:
class CompositeKey implements PartitionResolver {
private final Object idOne;
private final Object idTwo;
CompositeKey(Object idOne, Object idTwo) {
// argument validation as necessary
this.idOne = idOne;
this.idTwo = idTwo;
}
public String getName() {
return "MyCompositeKeyPartitionResolver";
}
public Object getRoutingObject() {
return idOne;
}
}
然后,您可以调用一个函数来查询您想要的结果,方法是使用...
Execution execution = FunctionService.onRegion("PartitionRegionName");
或者,您可以在调用函数时使用返回Execution
来过滤您想要查询(进一步限定)的(复杂)键...
ComplexKey filter = { .. };
execution.withFilter(Arrays.stream(filter).collect(Collectors.toSet()));
当然,如果您事先不知道您的密钥,这是有问题的。
然后您可能更喜欢使用 ComplexKey 来识别您的应用程序域对象,这在使用 SD[G] 的存储库抽象/扩展时是必需的:
@Region("MyPartitionRegion")
class ApplicationDomainObject {
@Id
CompositeKey identifier;
...
}
然后,您可以编写您的函数以对分区区域的“本地数据集”进行操作。也就是说,当集群中的一个数据节点托管相同的分区区域(PR)时,它只会对该 PR 的“桶”中的数据集进行操作,这通过执行以下操作来完成:
class QueryPartitionRegionFunction implements Function {
public void execute(FunctionContext<Object> functionContext) {
RegionFunctionContext regionFunctionContext =
(RegionFunctionContext) functionContext;
Region<ComplexKey, ApplicationDomainObject> localDataSet =
PartitionRegionHelper.getLocalDataForContext(regionFunctionContext);
SelectResults<?> resultSet =
localDataSet.query(String.format("identifier.idTwo = %s",
regionFunctionContext.getArguments);
// process result set and use ResultSender to send results
}
}
当然,使用SDG 的函数注释支持(即无论如何实现和调用你的函数),所有这些都更容易做到。
请注意,当您调用 时Function
,onRegion
使用 GemFireFunctionService
或更方便地使用 SDG 对函数执行的注释支持,如下所示:
@OnRegion("MyPartitionRegion")
interface MyPartitionRegionFunctions {
@FunctionId("QueryPartitionRegion")
<return-type> queryPartitionRegion(..);
}
然后..
Object resultSet = myPartitionRegionFunctions.queryPartitionRegion(..);
然后,FunctionContext
将是一个RegionFunctionContext
(因为您在 PR 上执行了函数,该函数在托管 PR 的集群中的所有节点上执行)。
此外,您使用 PartitionRegionHelper.getLocalDataForContext(:RegionFunctionContext) 来获取 PR 的本地数据集(即存储桶,或者只是该节点托管的整个 PR(跨所有节点)中的数据分片,这将基于你的“习惯” PartitionResolver
)。
然后,您可以查询以进一步限定或过滤感兴趣的数据。您可以看到我通过 查询(或进一步限定)idTwo
,这不是PartitionResolver
实现的一部分。此外,如果您没有在过滤器中指定键Execution
(因为我认为这将考虑整个“键”(idOne 和 idTwo),则仅在 (OQL) 查询谓词中需要),基于我们的你的类的正确实现Object.equals()
的方法ComplexKey
)。
但是,如果您事先不知道密钥和/或(特别是如果)您正在使用 SD[G] 的存储库,那么这ComplexKey
将成为您的应用程序域 abject 的一部分,然后您可以对其进行索引和查询(如上图所示:)identifier.idTwo = ?
。
希望这可以帮助!
注意:我没有对此进行任何测试,但希望它能为您指明正确的方向和/或为您提供进一步的想法。
推荐阅读
- php - 在角色之后过滤用户
- swift - tableView.selectRow has no effect when called within a UIContextualAction callback
- python - 正在发送的 python 邮件有一个空白的 TO 字段
- javascript - Websocket通过Javascript客户端发送图像文件
- excel - 有没有办法在excel中查找字符串前后有空格的文本?
- uwp - 如何使用通用 Windows 应用程序编辑 Word 文档中的书签
- node.js - postgres SQL查询在节点JS中引发错误
- c++ - lambda 如何为异步调用捕获自身?
- python - 在 MySql 中,使用 Python,如何根据变量 INSERT INTO 表和列?
- replace - db2中replace函数的起始位置