Lucene搜索后,获取文档中所有匹配单词的字符偏移量?(不仅仅是预览片段)
我正在使用lucene为大量HTML文档创建搜索引擎 我知道我可以使用Lucene搜索后,获取文档中所有匹配单词的字符偏移量?(不仅仅是预览片段),lucene,highlight,Lucene,Highlight,我正在使用lucene为大量HTML文档创建搜索引擎 我知道我可以使用PostingsHighlighter和friends来显示片段,用粗体字,类似于谷歌搜索结果,也类似于 但是,与这些示例不同,我需要一个解决方案,它可以保留突出显示的单词,即使用户打开匹配的文档后也是如此,类似于GoogleBooks 有些单词以的形式连字符。。。国际观众…我想我需要先将这些内容转换成纯文本,然后编写一些代码来合并连字符的单词,然后再将它们发送给lucene 一旦用户打开生成的文档,我希望可以使用lucene
PostingsHighlighter
和friends来显示片段,用粗体字,类似于谷歌搜索结果,也类似于
但是,与这些示例不同,我需要一个解决方案,它可以保留突出显示的单词,即使用户打开匹配的文档后也是如此,类似于GoogleBooks
有些单词以的形式连字符。。。国际观众…
我想我需要先将这些内容转换成纯文本,然后编写一些代码来合并连字符的单词,然后再将它们发送给lucene
一旦用户打开生成的文档,我希望可以使用lucene获得文档中每个匹配单词的字符偏移量
我必须将纯文本中的偏移量交叉引用回原始HTML,并编写代码以突出显示基于所述偏移量的单词
。。。国际观众…
我怎样才能从lucene那里得到我所需要的?当然,我不必为这个“最后一寸”写我自己的搜索?好的,我找到了一些可以开始的东西。:) 索引:
StandardAnalyzer analyzer - new StandardAnalyzer()
Directory index = FSDirectory.open(new File("...").toPath());
IndexWriterConfig config = new IndexWriterConfig(analyzer);
addDoc(writer, "...", "...");
addDoc(writer, "...", "...");
addDoc(writer, "...", "...");
// documents need to be read from the data source..
// only add once, or else your docs will be duplicated as you continue to use the system
writer.close();
指定要存储以突出显示的偏移量
private static final FieldType typeOffsets;
static {
typeOffsets = new FieldType(textField.TYPE_STORED);
typeOffsets.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
}
方法addDoc
void addDoc(IndexWriter writer, String title, String body) {
Document doc = new Document();
doc.add(new Field("title", body, typeOffsets));
doc.add(new Field("body", body, typeOffsets));
// you can also add an store a TextField that does not have offsets,
// like a file ID that you wouldn't search on, just need to reference original doc.
writer.addDocument(doc);
}
执行第一次搜索
String q = "...";
String[] fields = new String[] {"title", "body"};
QueryParser parser = new MultiFieldQueryParser(fields, analyzer)
Query query = parser.parse(q)
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(index));
PostingsHighlighter highlighter = new PostingsHighlighter();
TopDocs topDocs = searcher.search(query, 10, Sort.RELEVANCE);
使用highlighter.highlightFields(字段、查询、搜索器、topDocs)获取突出显示的代码段
。您可以对结果进行迭代
如果要突出显示结束文档(即,在搜索完成且用户选择了结果之后),请使用(需要进行较小的编辑)。它的工作原理是使用NullFragmenter
将整个内容转换为一个片段
public static String highlight(String pText, String pQuery) throws Exception
{
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
QueryParser parser = new QueryParser(Version.LUCENE_30, "", analyzer);
Highlighter highlighter = new Highlighter(new QueryScorer(parser.parse(pQuery)));
highlighter.setTextFragmenter(new NullFragmenter());
String text = highlighter.getBestFragment(analyzer, "", pText);
if (text != null)
{
return text;
}
return pText;
}
编辑:您实际上可以在最后一步中使用PostingsHighlighter
而不是Highlighter
,但您必须重写getBreakIterator
,然后重写BreakIterator
,使其认为整个文档是一个句子
编辑:您可以覆盖
getFormatter
来捕获偏移量,而不是试图解析通常由PostingHighlighter
输出的
标记,只是一条注释,因为我不确定这是否适合您的情况,但是如果您采用纯文本方式,您可以使用Highlighter
类以及编码器
的自定义实现(仅返回输入字符串的no op)和格式化程序
,后者仅收集匹配令牌的偏移量并返回空字符串。使用基本的QueryScorer
。适合我,但我只使用纯文本。有一种更好的方法是使用自定义分析器来处理块标记上的连字号。我可以骗lucene认为它只是在搜索纯文本文档,只要我能让它提供整个文档的突出显示,而不仅仅是相关的片段。我希望我能找到一个可以运行的示例来突出显示整个文档。您可以使用NullFragmenter
突出显示整个文档。谢谢,这就是我一直在寻找的答案。我现在要尝试实现一个。从开始,然后我将从这里展开。