我试图在FoundationDB的某个子空间中用getKey和KeySelector找到一个键。如果结果存在于子空间中,则效果很好。
val key = new Tuple().add(3)
val subspace = new Subspace(new Tuple().add("test-subspace"))
tr.set(key.pack(), new Tuple().pack())
tr.set(subspace.pack(key), new Tuple().pack())
tr.getKey(KeySelector.firstGreaterOrEqual(subspace.pack(key)))
.thenApply[Tuple] { result =>
println(Tuple.fromBytes(result)) // ("test-subspace", 3)
subspace.unpack(result) // (3)
}同时,如果目标子空间中不存在密钥,则返回在默认子空间中找到的me键。这不是我所期望的..。
val key = new Tuple().add(3)
val subspace = new Subspace(new Tuple().add("test-subspace"))
tr.set(key.pack(), new Tuple().pack())
tr.getKey(KeySelector.firstGreaterOrEqual(subspace.pack(key)))
.thenApply[Tuple] { result =>
println(Tuple.fromBytes(result)) // (3)
subspace.unpack(result) // Cannot unpack key that is not contained in subspace.
}此外,如果db为空,则getKey将返回一些Tuple.fromBytes无法解析的奇怪字节数组,而不是返回null。
val key = new Tuple().add("my-key")
tr.getKey(KeySelector.firstGreaterOrEqual(key.pack()))
.thenApply[Tuple] { result =>
println(result == null) // false
Tuple.fromBytes(result) // throws java.lang.IllegalArgumentException: Unknown tuple data type -1 at index 0
}当目标子空间不包含搜索结果时,我应该如何处理?
发布于 2018-11-14 18:33:33
这是预期的行为。键选择器返回与条件匹配的键--在本例中,第一个键大于或等于传递的byte[]。您需要根据您的子空间需求检查返回的密钥是否有效--方法是使用subspace.contains()或对返回的键进行任何其他验证。
对于第二个问题,同样的解释--返回的键可能是db中一些特殊的预先存在的行,而不是使用元组层创建的。因此,不能使用元组层来解析它。您需要使用subspace.contains或一些类似的检查来检查密钥有效性。
发布于 2018-11-26 17:20:07
要添加到瓜拉夫所说的内容,当密钥选择器在数据库开始之前解析为密钥时,它将返回空键('')。如果键在数据库结束后解析,您将在正常事务中获得'\xff',如果允许您的事务读取系统密钥,则获得'\xff\xff'。在关键选择器文档这里的末尾简要地提到了这一点。
至于不返回子空间之外的结果,这样做可能需要getKey接受一个绑定键参数,该参数限制了超出该键的搜索。它目前没有该参数,但如果使用限制为1,则可以使用getRange执行相同的查询。
tr.getRange(KeySelector.firstGreaterOrEqual(subspace.pack(key)), subspace.range().end, 1)在这种情况下,如果可以在匹配您的键选择器的子空间中找到一个键,则结果将有一个键,或者如果找不到,结果将为空。当然,您还将在这个查询中获得值。
https://stackoverflow.com/questions/53284066
复制相似问题