为了账号安全,请及时绑定邮箱和手机立即绑定

FoundationDB 中的 getKey 返回意外结果

FoundationDB 中的 getKey 返回意外结果

梦里花落0921 2022-01-19 12:35:08
我试图用 getKey 和 KeySelector 在 FoundationDB 的某个子空间中找到一个键。如果结果存在于子空间中,它会很好地工作。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)              }同时,如果目标子空间中不存在密钥,则返回在默认子空间中找到的密钥。这不是我所期望的......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 不会返回 null,而是返回一些无法被 Tuple.fromBytes 解析的奇怪字节数组。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              }当目标子空间不包含搜索结果时,我应该如何处理?
查看完整描述

2 回答

?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

补充一下 Guarav 所说的,当键选择器解析为数据库开始之前的键时,它会返回空键 ( '')。如果密钥在数据库末尾解析,您将进入'\xff'正常事务,或者'\xff\xff'您的事务被允许读取系统密钥。这在此处的键选择器文档的末尾简要提及。

至于不返回子空间之外的结果,这样做可能需要getKey接受一个绑定键参数,该参数限制搜索超出该键。它目前没有该参数,但getRange如果您使用 1 的限制,它可以并且可以用于执行相同的查询。例如,您可以执行以下操作:

tr.getRange(KeySelector.firstGreaterOrEqual(subspace.pack(key)), subspace.range().end, 1)

在这种情况下,如果可以在与您的键选择器匹配的子空间中找到一个键,则结果将具有一个键,如果不能,则该键将为空。当然,您还将在此查询中取回值。


查看完整回答
反对 回复 2022-01-19
?
千万里不及你

TA贡献1784条经验 获得超9个赞

这是预期的行为。Keyselector 返回与条件匹配的键 - 在这种情况下,第一个键大于或等于传递的字节 []。您需要根据您的子空间要求检查返回的密钥是否有效 - 通过使用 subspace.contains() 或对返回的密钥进行任何其他验证。

第二个问题的解释相同 - 返回的键可能是数据库中一些特殊的预先存在的行,它不是使用元组层创建的。因此它不能使用元组层解析。您需要使用 subspace.contains 或类似的检查来检查密钥的有效性。


查看完整回答
反对 回复 2022-01-19
  • 2 回答
  • 0 关注
  • 144 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信