Lucene搜索后,获取文档中所有匹配单词的字符偏移量?(不仅仅是预览片段)

Lucene搜索后,获取文档中所有匹配单词的字符偏移量?(不仅仅是预览片段),lucene,highlight,Lucene,Highlight,我正在使用lucene为大量HTML文档创建搜索引擎 我知道我可以使用PostingsHighlighter和friends来显示片段,用粗体字,类似于谷歌搜索结果,也类似于 但是,与这些示例不同,我需要一个解决方案,它可以保留突出显示的单词,即使用户打开匹配的文档后也是如此,类似于GoogleBooks 有些单词以的形式连字符。。。国际观众…我想我需要先将这些内容转换成纯文本,然后编写一些代码来合并连字符的单词,然后再将它们发送给lucene 一旦用户打开生成的文档,我希望可以使用lucene

我正在使用lucene为大量HTML文档创建搜索引擎

我知道我可以使用
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
突出显示整个文档。谢谢,这就是我一直在寻找的答案。我现在要尝试实现一个。从开始,然后我将从这里展开。