LMDB Java 检索具有相同键的所有值
LMDB Java retrieve all values with same key
我想用同一个键存储多个值。我确保在创建数据库时包含 MDB_DUPSORT
标志。我也知道这限制了值的大小,但在这种特定情况下这不是问题。
当我想用相同的键读取值时,我的问题就出现了。我进行了搜索,但找不到有关如何执行此操作的明确答案。
所以基本上:如何使用相同的键检索所有值?
我从数据库中使用 lmdbjava 到 read/write。
我试过了,但是迭代器继续下一个键,并且在读取最后一个值时不会停止:
try(Txn<ByteBuffer> txn = env.txnRead()) {
CursorIterator<ByteBuffer> cursor = db.iterate(txn, KeyRange.atLeast(key));
for(CursorIterator.KeyVal<ByteBuffer> kv : cursor.iterable()) {
ByteBuffer value = kv.val();
byte[] bytes = new byte[value.remaining()];
value.get(bytes);
System.out.println(bytes);
}
}
而不是 KeyRange.atLeast
根据 javadoc
starts on the passed key (or the first key immediately after it) and
iterate forward until no keys remain
我想你会想要使用 KeyRange.closed
Iterate forward between the passed keys, matching on the first keys
directly equal to the passed key (or immediately following it in the
case of the "start" key, or immediately preceding it in the case of
the "stop" key).
测试一下
@Test
public void dupSortKeyRange() {
final Dbi<ByteBuffer> db = env.openDbi(DB_1, MDB_CREATE, MDB_DUPSORT);
try (Txn<ByteBuffer> txn = env.txnWrite()) {
db.put(txn, bb(5), bb(6));
db.put(txn, bb(5), bb(7));
db.put(txn, bb(5), bb(8));
db.put(txn, bb(6), bb(9));
txn.commit();
}
try (Txn<ByteBuffer> txn = env.txnRead()) {
ByteBuffer key = bb(5);
List<Integer> keyValues = new ArrayList<>();
CursorIterator<ByteBuffer> cursor = db.iterate(txn, KeyRange.closed(key, key));
for (CursorIterator.KeyVal<ByteBuffer> kv : cursor.iterable()) {
ByteBuffer value = kv.val().get(new byte[kv.val().remaining()]);
keyValues.add(value.getInt(0));
}
assertEquals(3, keyValues.size(), 0);
assertTrue(keyValues.containsAll(Arrays.asList(6, 7, 8)));
}
}
我想用同一个键存储多个值。我确保在创建数据库时包含 MDB_DUPSORT
标志。我也知道这限制了值的大小,但在这种特定情况下这不是问题。
当我想用相同的键读取值时,我的问题就出现了。我进行了搜索,但找不到有关如何执行此操作的明确答案。
所以基本上:如何使用相同的键检索所有值?
我从数据库中使用 lmdbjava 到 read/write。
我试过了,但是迭代器继续下一个键,并且在读取最后一个值时不会停止:
try(Txn<ByteBuffer> txn = env.txnRead()) {
CursorIterator<ByteBuffer> cursor = db.iterate(txn, KeyRange.atLeast(key));
for(CursorIterator.KeyVal<ByteBuffer> kv : cursor.iterable()) {
ByteBuffer value = kv.val();
byte[] bytes = new byte[value.remaining()];
value.get(bytes);
System.out.println(bytes);
}
}
而不是 KeyRange.atLeast
根据 javadoc
starts on the passed key (or the first key immediately after it) and iterate forward until no keys remain
我想你会想要使用 KeyRange.closed
Iterate forward between the passed keys, matching on the first keys directly equal to the passed key (or immediately following it in the case of the "start" key, or immediately preceding it in the case of the "stop" key).
测试一下
@Test
public void dupSortKeyRange() {
final Dbi<ByteBuffer> db = env.openDbi(DB_1, MDB_CREATE, MDB_DUPSORT);
try (Txn<ByteBuffer> txn = env.txnWrite()) {
db.put(txn, bb(5), bb(6));
db.put(txn, bb(5), bb(7));
db.put(txn, bb(5), bb(8));
db.put(txn, bb(6), bb(9));
txn.commit();
}
try (Txn<ByteBuffer> txn = env.txnRead()) {
ByteBuffer key = bb(5);
List<Integer> keyValues = new ArrayList<>();
CursorIterator<ByteBuffer> cursor = db.iterate(txn, KeyRange.closed(key, key));
for (CursorIterator.KeyVal<ByteBuffer> kv : cursor.iterable()) {
ByteBuffer value = kv.val().get(new byte[kv.val().remaining()]);
keyValues.add(value.getInt(0));
}
assertEquals(3, keyValues.size(), 0);
assertTrue(keyValues.containsAll(Arrays.asList(6, 7, 8)));
}
}