所以我的一般问题是“是否有可能让 Accumulo BatchScanner 只拉回我给它的每个范围的第一个结果?”
现在有一些关于我的用例的细节,因为无论如何可能有更好的方法来解决这个问题。我有代表来自不同系统的消息的数据。可以有不同类型的消息。我的用户希望能够向系统提出问题,例如“给我在特定时间针对所有这些系统的特定类型的最新消息”。
我的表格布局看起来像这样
rowid: system_name, family: message_type, qualifier: masked_timestamp, value: message_text
这个想法是用户给我一个他们关心的系统列表、消息类型和某个时间戳。我使用了掩码时间戳,以便表格首先排序最近的。这样,当我扫描时间戳时,第一个结果是该时间之前的最新结果。我正在使用 BatchScanner,因为我有多个系统要搜索每个查询。我可以让 BatchScanner 只获取每个 Range 的第一个结果吗?我无法指定特定的键,因为最近的可能与用户给出的日期时间不匹配。
目前,我正在使用 BatchScanner 并忽略每个键的第一个结果以外的所有结果。它现在可以工作,但是当我只关心每个系统/类型的第一个结果时,通过网络拉回特定系统/类型的所有数据似乎是一种浪费。
编辑
我尝试使用 FirstEntryInRowIterator
@Test
public void testFirstEntryIterator() throws Exception
{
Connector connector = new MockInstance("inst").getConnector("user", new PasswordToken("password"));
connector.tableOperations().create("testing");
BatchWriter writer = writer(connector, "testing");
writer.addMutation(mutation("row", "fam", "qual1", "val1"));
writer.addMutation(mutation("row", "fam", "qual2", "val2"));
writer.addMutation(mutation("row", "fam", "qual3", "val3"));
writer.close();
Scanner scanner = connector.createScanner("testing", new Authorizations());
scanner.addScanIterator(new IteratorSetting(50, FirstEntryInRowIterator.class));
Key begin = new Key("row", "fam", "qual2");
scanner.setRange(new Range(begin, begin.followingKey(PartialKey.ROW_COLFAM_COLQUAL)));
int numResults = 0;
for (Map.Entry<Key, Value> entry : scanner)
{
Assert.assertEquals("qual2", entry.getKey().getColumnQualifier().toString());
numResults++;
}
Assert.assertEquals(1, numResults);
}
我的目标是返回的条目将是 ("row", "fam", "qual2", "val2") 但我得到 0 个结果。似乎 Iterator 在 Range 之前被应用了?我还没有深入研究这个。