如果键是GemFire区域中id1,id2的组合,并且Region被id1分区,那么获取所有键与id1匹配的行的最佳方法是什么。
我们正在考虑的选项:
在id1上创建另一个索引。如果我们这样做,我们想知道它是否违反所有分区区域?
编写数据感知功能,并按(id1,null)过滤以目标特定分区区域为目标。通过使用QueryService
在本地区域中使用索引?
请问是否还有其他方法可以通过部分键实现查询。
答案 0 :(得分:0)
嗯,可以通过在上面的“选项”中结合使用#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's Function annotation support(即无论如何实现和调用您的函数),所有这些操作都容易得多。
请注意,当您使用GemFire的Function
调用onRegion
,FunctionService
时,或更方便地使用SDG对函数执行的注释支持,就像这样:
@OnRegion("MyPartitionRegion")
interface MyPartitionRegionFunctions {
@FunctionId("QueryPartitionRegion")
<return-type> queryPartitionRegion(..);
}
然后..
Object resultSet = myPartitionRegionFunctions.queryPartitionRegion(..);
然后,FunctionContext
将是RegionFunctionContext
(因为您在PR上执行了Function,该函数在承载PR的群集中的所有节点上执行)。
此外,您还可以使用PartitionRegionHelper.getLocalDataForContext(:RegionFunctionContext)获取PR的本地数据集(即存储桶,或仅获取该节点托管的整个PR中(跨所有节点)的数据碎片),将基于您的“自定义” PartitionResolver
)。
然后您可以查询以进一步限定或过滤感兴趣的数据。您可以看到我是由idTwo
查询(或进一步限定)的,它不是PartitionResolver
实现的一部分。此外,仅当您未在过滤器中使用Execution
指定键时,才需要在(OQL)查询谓词中使用(因为我认为这会将整个“键”(idOne和idTwo)带入帐户,基于您的Object.equals()
类的ComplexKey
方法的正确实现)。
但是,如果您事先不知道密钥和/或(尤其是在使用SD [G]的存储库时),那么ComplexKey
将成为您应用程序域的一部分,您可以然后可以索引并查询(如上所示:identifier.idTwo = ?
)。
希望这会有所帮助!
注意:我还没有测试过任何一个,但是希望它能为您指明正确的方向和/或给您进一步的想法。