我試圖用 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)
在這種情況下,如果可以在與您的鍵選擇器匹配的子空間中找到一個鍵,則結果將具有一個鍵,如果不能,則該鍵將為空。當然,您還將在此查詢中取回值。

千萬里不及你
TA貢獻1784條經驗 獲得超9個贊
這是預期的行為。Keyselector 返回與條件匹配的鍵 - 在這種情況下,第一個鍵大于或等于傳遞的字節 []。您需要根據您的子空間要求檢查返回的密鑰是否有效 - 通過使用 subspace.contains() 或對返回的密鑰進行任何其他驗證。
第二個問題的解釋相同 - 返回的鍵可能是數據庫中一些特殊的預先存在的行,它不是使用元組層創建的。因此它不能使用元組層解析。您需要使用 subspace.contains 或類似的檢查來檢查密鑰的有效性。
添加回答
舉報
0/150
提交
取消