我有一个应用程序,该应用程序在索引中搜索具有未知前缀的匹配条形码,该条形码可能存在也可能不存在。当前,应用程序在 WildcardQuery 中使用前导通配符来说明前缀,但是,这显然会导致性能问题。我已经研究过使用ReverseStringFilter,但是它使用了TokenStream,并且不确定在这种情况下如何使用它。
这是当前实现方式的一个非常基本的示例,但是应该让您对正在发生的事情有一个很好的了解:
BooleanQuery allBCQueries;
BooleanQuery bcQuery;
for( barcode : barcodeList){
bcQuery.add( new WildcardQuery( new Term('barcode', "*" + barcode)), Occur.Must);
allBCQueries.add(bcQuery, Occur.should);
}
BooleanQuery result;
result.add(allBCQueries, Occur.Must);
然后将结果用于搜索索引。
有没有一种方法可以消除领先的通配符以提高性能?
答案 0 :(得分:0)
正如我在评论中所述-想法是使用ReverseStringFilter,它可以有效地还原令牌,而不是条形码“ 123123”会创建令牌“ 321321”。这意味着那些带有意外前缀的查询可以被重写。
我们可以使用查询barcode:*123
代替barcode:123*
,它会更加有效。
添加带有自定义TokenStream的文档非常简单:
final Tokenizer token = new KeywordTokenizer();
Document doc = new Document();
token.setReader(new StringReader(value));
doc.add(new TextField("barcode", value, Field.Store.YES));
doc.add(new TextField("reverse-barcode", new ReverseStringFilter(token)));
这样,我们在保留原始值的同时应用了关键字标记器(例如,没有标记器)+反向字符串过滤器
我已经对100万个填充有随机条形码的文档进行了一些测试(例如,我的情况是长整型),反向方法大约带来了 30%的优势,同时提供的结果数量完全相同。 / p>
可以找到完整的示例there