当键是id1、GemFire区域中的id2的组合并且区域用id1分区时,获取键与id1匹配的所有行的最佳方法是什么。
我们正在考虑的几个选项:
>
在id1上创建另一个索引。如果我们这样做,我们想知道它是否违反所有分区区域?
编写数据感知函数并按(id1, null)过滤以定位特定的分区区域。使用QueryService
在本地区域中使用索引?
你能让我知道是否有任何其他方法来实现部分键查询。
好吧,它可以通过在上面的“选项”中使用#1和#2的组合来实现(最佳情况下)(取决于您的应用程序域对象是否也存储/引用了密钥,如果您使用SD[G]存储库,情况就是如此。
这可能最好通过文档和示例来解释,特别是使用ParttionResolver
接口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
来过滤您在调用Function时想要查询(进一步限定)的(复杂)键…
ComplexKey filter = { .. };
execution.withFilter(Arrays.stream(filter).collect(Collectors.toSet()));
当然,如果你事先不知道你的钥匙,这是有问题的。
然后,您可能更喜欢使用ComplexKey来识别您的应用程序域对象,这在使用SD[G]的存储库抽象/扩展时是必要的:
@Region("MyPartitionRegion")
class ApplicationDomainObject {
@Id
CompositeKey identifier;
...
}
然后,您可以对Function进行编码,以对分区区域的“本地数据集”进行操作。也就是说,当集群中的数据节点托管相同的分区区域(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注释支持(即无论如何都要实现和调用您的Function)更容易做到这一切。
请注意,当您使用GemFire的FunctionService
调用Function
、onRegion
时,或者使用SDG对Function Execution的注释支持更方便,如下所示:
@OnRegion("MyPartitionRegion")
interface MyPartitionRegionFunctions {
@FunctionId("QueryPartitionRegion")
<return-type> queryPartitionRegion(..);
}
然后…
Object resultSet = myPartitionRegionFunctions.queryPartitionRegion(..);
然后,FunctionContext
将是一个Region onFunctionContext
(因为您在PR上执行了Function,它在托管PR的集群中的所有节点上执行)。
此外,您还可以使用(: Region onFunctionContext)来获取PR的本地数据集(即存储桶,或者仅仅是该节点托管的整个PR(所有节点)中的数据分片,这将基于您的自定义分区解析器
)。
然后,您可以查询以进一步限定,或过滤感兴趣的数据。您可以看到我通过idTwo
查询(或进一步限定),这不是分区解析器
实现的一部分。此外,只有在(OQL)查询谓词中,如果您没有使用执行
在过滤器中指定密钥(因为,我认为,这将需要整个“密钥”(idOne
但是,如果您事先不知道键和/或(特别是如果)您正在使用SD[G]的存储库,那么ComplexKey
将是您的应用程序域abject的一部分,然后您可以对其进行索引和查询(如上所示:标识符. idTwo = ?
)。
希望这有帮助!
注意:我没有测试过这些,但希望它能给你指明正确的方向和/或给你进一步的想法。