问题
I cant get a batch scanner to only scan for a specific row, when settings start and stop keys to the same thing I get no entry's back, when using an scanner I get this exception:
"java.lang.IllegalArgumentException: Start key must be less than end key in range (Test : [] 0 false, Test : [] 0 false)"...
I am writing in C# in Visual Studio 2010 and using Thrift (ver 0.9.1.1) and Accumulo's (ver 1.5.0) proxy.thrift code in the project.
Here is my code, everything "works" but I don't get any entries from client.nextK
class Program
{
static byte[] GetBytes(string str)
{
return Encoding.ASCII.GetBytes(str);
}
static string GetString(byte[] bytes)
{
return Encoding.ASCII.GetString(bytes);
}
static void Main(string[] args)
{
try
{
/** connect **/
TTransport transport = new TSocket("192.168.58.62", 42424);
transport = new TFramedTransport(transport);
TCompactProtocol protocol = new TCompactProtocol(transport);
transport.Open();
AccumuloProxy.Client client = new AccumuloProxy.Client(protocol);
Dictionary<string, string> passwd = new Dictionary<string,string>();
passwd.Add("password", "password");
var login = client.login("root", passwd);
/** connect end **/
/** Get all data from one "Row" **/
var bScanner = new BatchScanOptions();
Range range = new Range();
range.Start = new Key();
range.Start.Row = GetBytes("Test");
range.Stop = new Key();
range.Stop.Row = GetBytes("Test");
bScanner.Ranges = new List<Range>();
bScanner.Ranges.Add(range);
var scanId = client.createBatchScanner(login, "firstTable", bScanner);
var more = true;
while (more)
{
var scan = client.nextK(scanId, 10);
more = scan.More;
foreach (var entry in scan.Results)
{
Console.WriteLine("{0} {1}:{2} [{3}] {4}", GetString(entry.Key.Row), GetString(entry.Key.ColFamily), GetString(entry.Key.ColQualifier), GetString(entry.Key.ColVisibility), GetString(entry.Value));
}
}
client.closeScanner(scanId);
Console.WriteLine();
/** Get data end **/
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
The user manual for Accumulo 1.5, is showing this code snippet and that is the same as I'm doing (but in C#): (http://accumulo.apache.org/1.5/accumulo_user_manual.html#_basic_table)
Range r = new Range(userid, userid); // single row
Scanner s = conn.createScanner("userdata", auths);
s.setRange(r);
s.fetchColumnFamily(new Text("age"));
for(Entry<Key,Value> entry : s)
System.out.println(entry.getValue().toString());
回答1:
The problem is likely your range. In the Java API, you can construct a Range for a single row, with:
Range r = new Range("myRow");
In the thrift Proxy API, you can only give Keys to the Range constructor, not just RowIDs (this is an option in the Java API, also, but it is the only option in the Proxy API). Keys represent a single entry, so scanning:
R1:CF1:CQ1:CV1 -> R1:CF1:CQ1:CV1
will only ever result a scan over that one exact entry (and possibly all versions of it, if you don't have the VersioningIterator configured for the table).
So, if you want to scan all entries in row "a", you don't scan like this:
"a":null:null:null(inclusive) -> "a":null:null:null(inclusive)
Rather, you scan like this for row == "a":
"a":null:null:null(inclusive) -> "a\0":null:null:null(exclusive)
Or this, for row startsWith "a":
"a":null:null:null(inclusive) -> "b":null:null:null(exclusive)
回答2:
Have you already checked that possibility here? https://issues.apache.org/jira/browse/ACCUMULO-1189 It's fixed in Accumulo 1.5, you use 1.4, so seems worth a look.
来源:https://stackoverflow.com/questions/19055132/accumulo-createbatchscanner-range-not-working-as-expected