#spring-boot #spring-data #hbase #fuzzy-search
#spring-boot #spring-data #hbase #fuzzy-search
Вопрос:
Я пытаюсь выполнить нечеткий фильтр на основе маски в HBase, используя приложение Spring Boot с таблицей HBaseTemplate :
@Configuration public class HBaseConfig { @Bean public HbaseTemplate hbaseTemplate(org.apache.hadoop.conf.Configuration hadoopConfiguration) { return new HbaseTemplate(hadoopConfiguration); } }
Но у меня возникли проблемы с использованием HBaseTemplate для этого, вот мой тестовый код :
@Repository public class HBaseRepository { @Autowired private HbaseTemplate hbaseTemplate; public void performScan(String tableName, String valueToFind){ // Build filters for the search pattern String pattern = "??_" valueToFind "_?????"; FilterList filters = new FilterList(FilterList.Operator.MUST_PASS_ALL); Listlt;Pairlt;byte[], byte[]gt;gt; pairs = new ArrayListlt;gt;(); pairs.add(new Pair(Bytes.toBytesBinary(pattern), getMaskFromPattern(pattern))); filters.add(new FuzzyRowFilter(pairs)); Scan scan = new Scan(); scan.setFilter(filters); // toString is for testing purpose Listlt;Stringgt; result = hbaseTemplate.find(tableName, scan, (resultScanner -gt; StreamSupport.stream(Spliterators.spliteratorUnknownSize(resultScanner.iterator(), Spliterator.ORDERED), false) .map(Object::toString) .collect(Collectors.toList()))); } private static byte[] getMaskFromPattern(String pattern) { ByteArrayOutputStream mask = new ByteArrayOutputStream(); Arrays.stream(pattern.split("")).forEachOrdered(c -gt; { if (c.equals("?")) { mask.write(1); } else { mask.write(0); } }); return mask.toByteArray(); } }
Этот код, кажется, работает нормально, но запрос не возвращает никакого результата.
Теперь, если я выполню точно такое же сканирование на той же таблице, но без использования HBaseTemplate :
@Repository public class HBaseRepository { @Autowired private HbaseTemplate hbaseTemplate; public void performScan(String tableName, String valueToFind){ // Build filters for the search pattern String pattern = "??_" valueToFind "_?????"; FilterList filters = new FilterList(FilterList.Operator.MUST_PASS_ALL); Listlt;Pairlt;byte[], byte[]gt;gt; pairs = new ArrayListlt;gt;(); patterns.forEach(pattern -gt; pairs.add(new Pair(Bytes.toBytesBinary(pattern), getMaskFromPattern(pattern)))); filters.add(new FuzzyRowFilter(pairs)); Scan scan = new Scan(); scan.setFilter(filters); // Using raw connection instead of HBaseTemplate Connection connection = ConnectionFactory.createConnection(hbaseTemplate.getConfiguration(), (ExecutorService) null, (User) null); ResultScanner resultScanner = connection.getTable(TableName.valueOf(tableName)).getScanner(scan); // toString is for testing purpose Listlt;Stringgt; strings = StreamSupport .stream(Spliterators.spliteratorUnknownSize(resultScanner.iterator(), Spliterator.ORDERED), false) .map(Object::toString) .collect(Collectors.toList()); } private static byte[] getMaskFromPattern(String pattern) { ByteArrayOutputStream mask = new ByteArrayOutputStream(); Arrays.stream(pattern.split("")).forEachOrdered(c -gt; { if (c.equals("?")) { mask.write(1); } else { mask.write(0); } }); return mask.toByteArray(); } }
Now this code returns many results…
I’ve used HBaseTemplate before but this is the first time I try to use fuzzy filter on it. In the documentation I don’t see any known restriction on using this kind of filters with HBaseTemplate, so why it doesn’t work properly ?