java - 累积范围 - 不包含结束键
问题描述
我正在学习 Accumulo,似乎无法让 Range 中指定的结束键包含在内。我的代码如下。我曾尝试将其明确设置endKeyInclusive
为true
in Range
,但这并没有帮助。
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 )
as 字节数组构建结束键,并将键的其余维度( 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
)。
推荐阅读
- python - OpenCV如何立体校准和三角测量点?
- python - 如何在烧瓶中的一行中返回 json 响应?
- javascript - 在页面加载时对 HTML 元素调用 javascript 函数
- css - CSS堆叠上下文影响SVG不透明度?
- java - 一段时间后,带有 Spring 安全性的 Spring Boot 自动停止工作
- c# - 隐式转换
- node.js - Heroku Redis 附加组件错误错误:1408F10B:SSL 例程:ssl3_get_record:错误的版本号
- kivy - Kivy 观察属性变化
- google-sheets - 如何根据一个单元格与多个相邻单元格作为今天的日期来镜像单元格
- node.js - 成功登录后未触发firebase onAuthStateChanged