我正在使用RocksDbSharp库,该库是C#中来自Facebook的RocksDb的实现。我想通过一个键来过滤我的记录,但是不幸的是,我没有看到如何执行此操作的选项。这是示例代码:
static void Main(string[] args)
{
string directory = @"C:\Path\To\RocksDB\Storage";
DbOptions options = new DbOptions().SetCreateIfMissing(true);
using (RocksDb rocksDb = RocksDb.Open(options, directory))
{
rocksDb.Put("AAAAB", "Test 1");
rocksDb.Put("AAABB", "Test 2");
rocksDb.Put("AABBB", "Test 3");
rocksDb.Put("ABBBB", "Test 4");
rocksDb.Put("BBBBB", "Test 5");
List<string> keys = new List<string>();
using (Iterator iterator = rocksDb.NewIterator())
{
iterator.Seek("AAB");
while (iterator.Valid())
{
keys.Add(iterator.StringKey());
iterator.Next();
}
}
Console.WriteLine(string.Join(", ", keys));
Console.ReadLine();
}
}
输出为:
AABBB,ABBBB,BBBBB
如何更改它,因此输出仅为AABBB
?我读了Iterator wiki和Prefix Seek API,可以将prefix_same_as_start
设置为true
:
如果前缀的键没有等于或大于lookup_key,或者在调用一个或多个Next()之后,我们完成了该前缀的所有键,则可能返回Valid()= false或任何大于上一个键,具体取决于ReadOptions.prefix_same_as_start = true。
此外,对此ticket进行了解释:
如果只希望键以前缀002开头,请使用read_options.prefix_same_as_start,该键仅显示与查找时具有相同前缀的键。
如何将该属性设置为true?如果检查ReadOptions class的实现,将找不到设置此属性的任何内容。我还有其他过滤键的选项吗?
答案 0 :(得分:0)
要通过前缀检索,应首先创建一个前缀提取器。
Options options;
options.prefix_extractor.reset(NewFixedPrefixTransform(<Length of the prefix>));
并使用这些选项打开数据库。
在ReadOptions中将prefix_same_as_start设置为true。
以下代码段可能会帮助您(尽管使用C ++编写)
int main()
{
DB *db;
Options options;
options.IncreaseParallelism();
options.OptimizeLevelStyleCompaction();
options.create_if_missing = true;
options.prefix_extractor.reset(NewFixedPrefixTransform(3));
Status s = DB::Open(options, kDBPath, &db);
assert(s.ok());
s = db->Put(WriteOptions(), "AAAAB", "value1");
assert(s.ok());
s = db->Put(WriteOptions(), "AAABB", "value2");
assert(s.ok());
s = db->Put(WriteOptions(), "AABBB", "value3");
assert(s.ok());
s = db->Put(WriteOptions(), "ABBBB", "value4");
assert(s.ok());
s = db->Put(WriteOptions(), "BBBBB", "value5");
assert(s.ok());
ReadOptions read_options;
read_options.prefix_same_as_start = true;
Iterator *iter = db->NewIterator(read_options);
iter->Seek("AAB");
while (iter->Valid())
{
printf("key %s\n", iter->key().ToString().c_str());
iter->Next();
}
delete iter;
delete db;
return 0;
}
由于rocksdb是用c ++编写的,因此如果不存在,则将you might want to write a wrapper function
用于prefix_same_as_start并将其包括在内。
对于包装函数示例,在rocksdb本机代码中,有文件c.cc/c.h用C语言为各种rocksdb选项编写包装函数。您可以用C#编写一个以满足您的要求。 :)