Lucene 6.6:当前使用分析器和过滤器创建自定义查询的方法是什么?
Lucene 6.6: What is the current way to create a custom query using analyzers and filters?
我正在使用 lucene 6.6.0 开发搜索服务,但我对如何创建自定义分析器和查询感到很困惑。
我已经根据来自 rdbms 的数据编写了我的索引,起初我只是使用标准分析器。不幸的是,它似乎没有用“_”、“-”或数字等特殊字符来分割文本,它只用空格来标记。我找到了 WordDelimiterGraphFilter,它似乎可以做我想做的,但我不明白如何让它工作。现在我尝试像这样使用它:
mCustomAnalyzer = new Analyzer()
{
@Override
protected TokenStreamComponents createComponents(String fieldName) {
Tokenizer source = new StandardTokenizer();
TokenStream filter = new WordDelimiterGraphFilter(source, 8, null);
return new TokenStreamComponents(source, filter);
}
};
QueryBuilder queryBuilder = new QueryBuilder(mCustomAnalyzer);
Query query = queryBuilder.createPhraseQuery(aField, aText, 15);
对于索引,我使用相同的分析器。但是它不起作用:如果我搜索 "term1 term2" 我希望找到像 "term1_term2" 和 "term32423" 或 "term_232".
这样的东西
我在这里错过了什么?我尝试了不同的整数作为过滤器 [1] 的 "configurationFlag" 参数,但它似乎不起作用...
不清楚你在索引什么,在搜索什么。在您的示例代码中,您将标志作为 CATENATE_NUMBERS(8) 传递,这对文本没有真正帮助,它只会连接数字,例如:500-42 -> 50042。
要将 term1_term2 拆分为 term1, term2, term1term2, term1_term2 你需要使用 GENERATE_WORD_PARTS
, CATENATE_WORDS
、CATENATE_NUMBERS
、CATENATE_ALL
、PRESERVE_ORIGIN
标志。
private static class CustomAnalyzer extends Analyzer{
@Override
protected TokenStreamComponents createComponents(String fieldName) {
final int flags = GENERATE_WORD_PARTS|CATENATE_WORDS|CATENATE_NUMBERS|CATENATE_ALL|PRESERVE_ORIGINAL;
Tokenizer tokenizer = new StandardTokenizer();
return new TokenStreamComponents(tokenizer,new WordDelimiterGraphFilter(tokenizer, flags, null ));
}
}
用于测试您的示例的示例代码 -
CustomAnalyzer customAnalyzer = new CustomAnalyzer();
Directory directory = FSDirectory.open(Paths.get("directoryPath"));
IndexWriter writer = new IndexWriter(directory, new IndexWriterConfig(customAnalyzer));
Document doc1 = new Document();
doc1.add(new TextField("text", "WAS_sample_tc", Field.Store.YES));
writer.addDocument(doc1);
writer.close();
QueryBuilder queryBuilder = new QueryBuilder(customAnalyzer);
Query query = queryBuilder.createPhraseQuery("text", "sample", 15);
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(directory));
TopDocs topDocs = searcher.search(query, 10);
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
Document doc = searcher.doc(scoreDoc.doc);
System.out.println(doc.toString());
}
我正在使用 lucene 6.6.0 开发搜索服务,但我对如何创建自定义分析器和查询感到很困惑。
我已经根据来自 rdbms 的数据编写了我的索引,起初我只是使用标准分析器。不幸的是,它似乎没有用“_”、“-”或数字等特殊字符来分割文本,它只用空格来标记。我找到了 WordDelimiterGraphFilter,它似乎可以做我想做的,但我不明白如何让它工作。现在我尝试像这样使用它:
mCustomAnalyzer = new Analyzer()
{
@Override
protected TokenStreamComponents createComponents(String fieldName) {
Tokenizer source = new StandardTokenizer();
TokenStream filter = new WordDelimiterGraphFilter(source, 8, null);
return new TokenStreamComponents(source, filter);
}
};
QueryBuilder queryBuilder = new QueryBuilder(mCustomAnalyzer);
Query query = queryBuilder.createPhraseQuery(aField, aText, 15);
对于索引,我使用相同的分析器。但是它不起作用:如果我搜索 "term1 term2" 我希望找到像 "term1_term2" 和 "term32423" 或 "term_232".
这样的东西我在这里错过了什么?我尝试了不同的整数作为过滤器 [1] 的 "configurationFlag" 参数,但它似乎不起作用...
不清楚你在索引什么,在搜索什么。在您的示例代码中,您将标志作为 CATENATE_NUMBERS(8) 传递,这对文本没有真正帮助,它只会连接数字,例如:500-42 -> 50042。
要将 term1_term2 拆分为 term1, term2, term1term2, term1_term2 你需要使用 GENERATE_WORD_PARTS
, CATENATE_WORDS
、CATENATE_NUMBERS
、CATENATE_ALL
、PRESERVE_ORIGIN
标志。
private static class CustomAnalyzer extends Analyzer{
@Override
protected TokenStreamComponents createComponents(String fieldName) {
final int flags = GENERATE_WORD_PARTS|CATENATE_WORDS|CATENATE_NUMBERS|CATENATE_ALL|PRESERVE_ORIGINAL;
Tokenizer tokenizer = new StandardTokenizer();
return new TokenStreamComponents(tokenizer,new WordDelimiterGraphFilter(tokenizer, flags, null ));
}
}
用于测试您的示例的示例代码 -
CustomAnalyzer customAnalyzer = new CustomAnalyzer();
Directory directory = FSDirectory.open(Paths.get("directoryPath"));
IndexWriter writer = new IndexWriter(directory, new IndexWriterConfig(customAnalyzer));
Document doc1 = new Document();
doc1.add(new TextField("text", "WAS_sample_tc", Field.Store.YES));
writer.addDocument(doc1);
writer.close();
QueryBuilder queryBuilder = new QueryBuilder(customAnalyzer);
Query query = queryBuilder.createPhraseQuery("text", "sample", 15);
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(directory));
TopDocs topDocs = searcher.search(query, 10);
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
Document doc = searcher.doc(scoreDoc.doc);
System.out.println(doc.toString());
}