大多数阅读标题的人都可能对Lucene有所了解,不需要进一步解释。 NB我使用Jython但我认为大多数Java用户都会理解Java等价物......
这是一个经典的事情:你的搜索字符串中有多个术语......在Lucene术语中,这会返回一个BooleanQuery。然后你使用类似这样的代码突出显示(NB我是一个Lucene新手,这都是从网络示例中调整的):
yellow_highlight = SimpleHTMLFormatter( '<b style="background-color:yellow">', '</b>' )
green_highlight = SimpleHTMLFormatter( '<b style="background-color:green">', '</b>' )
...
stream = FrenchAnalyzer( Version.LUCENE_46 ).tokenStream( "both", StringReader( both ) )
scorer = QueryScorer( fr_query, "both" )
fragmenter = SimpleSpanFragmenter(scorer)
highlighter = Highlighter( yellow_highlight, scorer )
highlighter.setTextFragmenter(fragmenter)
best_fragments = highlighter.getBestTextFragments( stream, both, True, 5 )
if best_fragments:
for best_frag in best_fragments:
print "=== best frag: %s, type %s" % ( best_frag, type( best_frag ))
html_text += "&bull %s<br>\n" % unicode( best_frag )
...然后将html_text放在JTextPane中。
但是,如何使查询中的第一个单词以黄色背景突出显示,第二个单词以绿色背景突出显示?我试图理解org.apache.lucene.search中的各种类......无济于事。所以我唯一的学习方式是谷歌搜索。我找不到任何线索......
答案 0 :(得分:0)
四年前我问过这个问题......当时我确实设法使用javax.swing.text.html.HTMLDocument
来实现解决方案。标准Java库中还有接口org.w3c.dom.html.HTMLDocument
。这种方式很难。
但对于任何有兴趣的人来说,这是一个更简单的解决方案。利用Lucene的SimpleHTMLFormatter
返回最简单的“标记”文本的事实:选择的单词用HTML B
标记突出显示。而已。它甚至不是一个“正确”的HTML片段,只有一个String
,其中包含<B>
和</B>
。
多字查询会生成BooleanQuery
...您可以通过TermQuery
... booleanQuery.clauses()
getQuery()
我在Groovy工作。我想要应用的着色是控制台代码,根据BASH(或Cygwin)。其他类型的着色可以在这个模型上得到解决。
所以你先设置一张地图来保存你的“标记细节”:
def markupDetails = [:]
然后对于每个TermQuery
,您每次使用相同的text
参数调用此参数,为每个术语规定不同的colour
参数。 NB我正在使用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
}
}
}
正如我所说,我想要控制台输出。此处方法中的colour
参数是根据找到的控制台颜色代码here。例如。黄色是\033[033m
。 ConsoleColors.RESET
为\033[0m
,用于标记每个彩色文本位置停止的位置。
...在您完成所有TermQuery
之后,您将获得一张漂亮的地图,告诉您各个颜色的开始和结束位置。您从文本末尾向后工作,以便在String
的正确位置插入“标记”。在这里注意text
是原始的无标记的String
:
markupDetails.sort().reverseEach{ pos, markup ->
String firstPart = text.substring( 0, pos )
String secondPart = text.substring( pos )
text = firstPart + markup + secondPart
}
...最后text
包含您标记的String
:打印到控制台。可爱。