![](/img/trans.png)
[英]ArrayIndexOutOfBoundsException when running range query in Accumulo
[英]Accumulo Range - End Key Not Inclusive
我正在學習Accumulo,似乎無法獲取Range中包含的結束鍵。 我的代碼如下。 我嘗試在Range
中將endKeyInclusive
顯式設置為true
,但這沒有幫助。
BatchWriter writer = conn.createBatchWriter("table", config);
List<String> deterTimes = new ArrayList<>();
String rowId = "3015551212<ll>";
String columnFamily = "deter";
for (int i = 0; i < 10; i++) {
String deterTime = "20181112:21:46:33" + i;
deterTimes.add(deterTime);
writer.addMutation(makeRecord(rowId, columnFamily, deterTime, "DETER" + i));
}
writer.flush();
writer.close();
Scanner scan = conn.createScanner("table", auths);
Key startKey = new Key(rowId.getBytes(), columnFamily.getBytes(), deterTimes.get(1).getBytes());
Key endKey = new Key(rowId.getBytes(), columnFamily.getBytes(), deterTimes.get(4).getBytes());
Range range = new Range(startKey, endKey);
if (range.isEndKeyInclusive()) System.out.println("true");
scan.setRange(range);
for (Entry<Key,Value> entry : scan) {
Text row = entry.getKey().getRow();
Text cq = entry.getKey().getColumnQualifier();
Value value = entry.getValue();
System.out.println("Fetched row " + row + " with value: " + value + ", cq=" + cq);
}
輸出:
true
Fetched row 3015551212<ll> with value: DETER1, cq='20181112:21:46:331'
Fetched row 3015551212<ll> with value: DETER2, cq='20181112:21:46:332'
Fetched row 3015551212<ll> with value: DETER3, cq='20181112:21:46:333'
您正在使用( row, column family, column qualifier )
作為字節數組構造結束鍵,並且鍵的其余維( column visibility, timestamp )
設置為默認值(具體來說,是一個空字節數組和Long.MAX_VALUE
。 )。
掃描儀將停止在該確切鍵處(包括端值)。 但是,您的實際數據輸入幾乎肯定不是那個確切的密鑰(您沒有提供makeRecord
的實現來進行驗證)。 即使您的數據實際上具有空的列可見性,時間戳也幾乎可以肯定不是Long.MAX_VALUE
,而是您在makeRecord
實現中設置的或者基於tserver的時間或某些表邏輯計數器設置的。 由於密鑰的時間戳維按降序排列,因此掃描儀將在到達條目之前停止在Long.MAX_LONG
查找數據。
這有點像在搜索字典中尋找analogy
,但是在達到analog
時停止:您將錯過以analog
開頭的其余單詞。
基於精確鍵構造范圍時,這是一個常見的陷阱。 通常最好基於行構造范圍(包括行將包括整個行),而不要構造鍵( 為此存在Range
構造函數 )。 或者,指定結束鍵以使其獨占工作。 您可以通過在該列的最后一個有意義的元素的末尾附加一個空字節來做到這一點。 例如,您可以執行以下操作:
Key endKey = new Key(rowId.getBytes(),
columnFamily.getBytes(),
(deterTimes.get(4) + "\0").getBytes());
Range range = new Range(startKey, true, endKey, false);
您應該注意的另一個陷阱是使用String.getBytes()
獲取字節數組,而不指定編碼。 最好使用一致的內容,例如"abc".getBytes(StandardCharsets.UTF_8)
(不過,我通常會進行靜態導入,因此只能指定UTF_8
)。
范圍在此處運行,但您添加的值可能存在問題
這將更易於通過輸出進行診斷,但是您是否有可能期望將deterTime高一,因為數組從零開始,所以您看到的deterTime比預期小一?
如果不是這種情況,請分享您的輸出
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.