Lucene Highlighter类:以不同颜色突出显示不同的单词
也许大多数读过这本书的人都对Lucene略知一二,不需要进一步解释。注意:我使用Jython,但我认为大多数Java用户都会理解Java的等价物 这是一件经典的事情:您的搜索字符串中有多个词。。。用Lucene术语来说,它返回一个布尔查询。然后,您可以使用类似于此的代码来突出显示(注意,我是Lucene新手,这都是从网络示例中精心设计的):Lucene Highlighter类:以不同颜色突出显示不同的单词,lucene,highlighting,Lucene,Highlighting,也许大多数读过这本书的人都对Lucene略知一二,不需要进一步解释。注意:我使用Jython,但我认为大多数Java用户都会理解Java的等价物 这是一件经典的事情:您的搜索字符串中有多个词。。。用Lucene术语来说,它返回一个布尔查询。然后,您可以使用类似于此的代码来突出显示(注意,我是Lucene新手,这都是从网络示例中精心设计的): yellow\u highlight=SimpleHTMLFormatter(“”,“”) 绿色突出显示=SimpleHTMLFormatter(“”,“”
yellow\u highlight=SimpleHTMLFormatter(“”,“”)
绿色突出显示=SimpleHTMLFormatter(“”,“”)
...
stream=FrenchAnalyzer(Version.LUCENE_46)。令牌流(“两者”,StringReader(两者))
记分员=查询记分员(fr_查询,“两者”)
fragmenter=SimplePanFragmenter(记分员)
荧光笔=荧光笔(黄色突出显示,记分员)
highlighter.setTextFragmenter(碎片器)
best_fragments=highlighter.getBestTextFragments(流,两者,True,5)
如果最好的话:
对于最佳碎片中的最佳碎片:
打印“==最佳帧:%s,类型%s”%(最佳帧,类型(最佳帧))
html\u text+=“&bull%s
\n”%unicode(最佳格式)
。。。然后将html_文本放入例如JTextPane中
但是,如何使查询中的第一个单词以黄色背景突出显示,第二个单词以绿色背景突出显示?我试图理解org.apache.lucene.search中的各种类。。。无济于事。所以我唯一的学习方式就是谷歌搜索。我找不到任何线索……四年前我问过这个问题。。。当时我确实使用
javax.swing.text.html.HTMLDocument
实现了一个解决方案。标准Java库中还有接口org.w3c.dom.html.HTMLDocument
。这样做很辛苦
但对于任何感兴趣的人来说,有一个简单得多的解决方案。利用Lucene的SimpleHTMLFormatter
返回最简单的可想象的“标记”文本:所选单词用HTMLB
标记突出显示。就这样。它甚至不是一个“正确的”HTML片段,只是一个字符串,其中包含
s和
s
多词查询生成布尔查询
。。。通过转到booleanQuery.子句()
,可以从中提取多个TermQuery
s<代码>getQuery()
我在Groovy工作。我想应用的颜色是控制台代码,如BASH(或Cygwin)。其他类型的颜色可以在这个模型上计算出来
因此,您在保存“标记详细信息”之前设置了一个映射:
然后,对于每个术语查询
,您调用它,每次使用相同的文本
参数,为每个术语规定不同的颜色
参数。注意,我用的是Lucene 6
def createHighlightAndAnalyseMarkup( TermQuery tq, String text, String colour ) {
def termQueryScorer = new QueryScorer( tq )
def termQueryHighlighter = new Highlighter( formatter, termQueryScorer )
TokenStream stream = TokenSources.getTokenStream( fieldName, null, text, analyser, -1 )
String[] frags = termQueryHighlighter.getBestFragments( stream, text, 999999 )
// not sure under what circs you get > 1 fragment...
assert frags.size() <= 1
// NB you don't always get all terms in all returned LDocuments...
if( frags.size() ) {
String highlightedFrag = frags[ 0 ]
Matcher boldTagMatcher = highlightedFrag =~ /<\/?B>/
def pos = 0
def previousEnd = 0
while( boldTagMatcher.find()) {
pos += boldTagMatcher.start() - previousEnd
previousEnd = boldTagMatcher.end()
markupDetails[ pos ] = boldTagMatcher.group() == '<B>'? colour : ConsoleColors.RESET
}
}
}
。。。在包含标记的
字符串的文本
末尾:打印到控制台。可爱。我想看看。它是根据本学期的IDF分数来做的,这不是你想要的,但这可能是最好的起点。你能回答你的问题,而不是编辑问题本身吗?
def markupDetails = [:]
def createHighlightAndAnalyseMarkup( TermQuery tq, String text, String colour ) {
def termQueryScorer = new QueryScorer( tq )
def termQueryHighlighter = new Highlighter( formatter, termQueryScorer )
TokenStream stream = TokenSources.getTokenStream( fieldName, null, text, analyser, -1 )
String[] frags = termQueryHighlighter.getBestFragments( stream, text, 999999 )
// not sure under what circs you get > 1 fragment...
assert frags.size() <= 1
// NB you don't always get all terms in all returned LDocuments...
if( frags.size() ) {
String highlightedFrag = frags[ 0 ]
Matcher boldTagMatcher = highlightedFrag =~ /<\/?B>/
def pos = 0
def previousEnd = 0
while( boldTagMatcher.find()) {
pos += boldTagMatcher.start() - previousEnd
previousEnd = boldTagMatcher.end()
markupDetails[ pos ] = boldTagMatcher.group() == '<B>'? colour : ConsoleColors.RESET
}
}
}
markupDetails.sort().reverseEach{ pos, markup ->
String firstPart = text.substring( 0, pos )
String secondPart = text.substring( pos )
text = firstPart + markup + secondPart
}