C# Lucene.net范围查询+;突出显示

C# Lucene.net范围查询+;突出显示,c#,.net,lucene,lucene.net,C#,.net,Lucene,Lucene.net,另一个Lucene.net问题是一个极端的新手提出的 这一次,我发现了一个有趣的问题,即使用一个包含范围的查询并使用高亮显示 我是凭记忆写的,所以请原谅任何语法错误 我有一个假设的Lucene指数: --------------------------------------------------------- | date | text | ----------------------------------

另一个Lucene.net问题是一个极端的新手提出的

这一次,我发现了一个有趣的问题,即使用一个包含范围的查询并使用高亮显示

我是凭记忆写的,所以请原谅任何语法错误

我有一个假设的Lucene指数:

---------------------------------------------------------
|       date         |               text               |
---------------------------------------------------------
|     1317809124     |       a crazy block of text      |
---------------------------------------------------------
|     1317809284     |       programmers are crazy      |
---------------------------------------------------------

** date is a unix timestamp        
。。。它们已通过以下方式添加到索引中:

Lucene.Net.Documents.Document doc = new Lucene.Net.Documents.Document();
doc.Add(new Lucene.Net.Documents.Field("text", "some block of text", Lucene.Net.Documents.Field.Store.YES, Lucene.Net.Documents.Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS));
doc.Add(new Lucene.Net.Documents.Field("date", "some unix timestamp", Lucene.Net.Documents.Field.Store.YES, Lucene.Net.Documents.Field.Index.NOT_ANALYZED));
这就是我查询Lucene的方式:

Lucene.Net.Analysis.Standard.StandardAnalyzer analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29);
Lucene.Net.Search.IndexSearcher searcher = new Lucene.Net.Search.IndexSearcher(Lucene.Net.Store.FSDirectory.Open(_headlinesDirectory), true);
Lucene.Net.QueryParsers.QueryParser parser = new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_29, "text", analyzer);
Lucene.Net.Search.Query query = parser.Parse(queryPhrase);
Lucene.Net.Search.Hits hits = searcher.Search(query);

// code highlighting
Lucene.Net.Highlight.Formatter formatter = new Lucene.Net.Highlight.SimpleHTMLFormatter("<span style=\"background:yellow;\">","</span>");
Lucene.Net.Highlight.SimpleFragmenter fragmenter = new Lucene.Net.Highlight.SimpleFragmenter(50);
Lucene.Net.Highlight.QueryScorer scorer = new Lucene.Net.Highlight.QueryScorer(query);
Lucene.Net.Highlight.Highlighter highlighter = new Lucene.Net.Highlight.Highlighter(formatter, scorer);
highlighter.SetTextFragmenter(fragmenter);     

for (int i = 0; i < hits.Length(); i++)
{
    Lucene.Net.Documents.Document doc = hits.Doc(i);
    Lucene.Net.Analysis.TokenStream stream = analyzer.TokenStream("", new StringReader(doc.Get("text")));
    string highlightedText = highlighter.GetBestFragments(stream, doc.Get("text"), 1, "...");
    Console.WriteLine("--> " + highlightedText);
}
查询时,它会查找“疯狂”的所有结果,但不会输出任何突出显示的文本

删除日期范围后,您只需查询术语:

crazy
。。。这一次高亮显示工作正常

我的实现中是否有什么地方做错了,我是否应该考虑一个新的实现,或者这是一个已知的问题,可能需要解决

提前感谢stackeroverflow'ers:)

--编辑--

我已经实现了LB的建议(顺便说一句,太棒了!)。我仍然不知道为什么这样做有效,因为我认为Lucene是完全的巫毒或编程巫术,但确实如此,我很高兴:)

为完整起见,以下是修改后的代码:

Lucene.Net.Analysis.Standard.StandardAnalyzer analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29);
Lucene.Net.Search.IndexSearcher searcher = new Lucene.Net.Search.IndexSearcher(Lucene.Net.Store.FSDirectory.Open(_headlinesDirectory), true);
Lucene.Net.QueryParsers.QueryParser parser = new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_29, "text", analyzer);

// new line here
parser.SetMultiTermRewriteMethod(Lucene.Net.Search.MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);

Lucene.Net.Search.Query query = parser.Parse(queryPhrase);

// new line here
Lucene.Net.Search.Query query2 = query.Rewrite(searcher.GetIndexReader());
Lucene.Net.Search.Hits hits = searcher.Search(query);

// code highlighting
Lucene.Net.Highlight.Formatter formatter = new Lucene.Net.Highlight.SimpleHTMLFormatter("<span style=\"background:yellow;\">","</span>");
Lucene.Net.Highlight.SimpleFragmenter fragmenter = new Lucene.Net.Highlight.SimpleFragmenter(50);

// changed to use query2
Lucene.Net.Highlight.QueryScorer scorer = new Lucene.Net.Highlight.QueryScorer(query2);

Lucene.Net.Highlight.Highlighter highlighter = new Lucene.Net.Highlight.Highlighter(formatter, scorer);
highlighter.SetTextFragmenter(fragmenter);

for (int i = 0; i < hits.Length(); i++)
{
    Lucene.Net.Documents.Document doc = hits.Doc(i);
    Lucene.Net.Analysis.TokenStream stream = analyzer.TokenStream("", new StringReader(doc.Get("text")));
    string highlightedText = highlighter.GetBestFragments(stream, doc.Get("text"), 1, "...");
    Console.WriteLine("--> " + highlightedText);
}
Lucene.Net.Analysis.Standard.StandardAnalyzer analyzer=新的Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.Lucene_29);
Lucene.Net.Search.IndexSearcher searcher=new Lucene.Net.Search.IndexSearcher(Lucene.Net.Store.FSDirectory.Open(_headlinesDirectory),true);
Lucene.Net.QueryParsers.QueryParser=新的Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.lucene29,“文本”,分析器);
//这里是新线
SetMultiTermRewriteMethod(Lucene.Net.Search.MultiTermQuery.SCORING\u BOOLEAN\u QUERY\u REWRITE);
Lucene.Net.Search.Query Query=parser.Parse(queryPhrase);
//这里是新线
Lucene.Net.Search.Query query2=Query.Rewrite(searcher.GetIndexReader());
Lucene.Net.Search.Hits=searcher.Search(查询);
//代码突出显示
Lucene.Net.Highlight.Formatter Formatter=新的Lucene.Net.Highlight.SimpleHTMLFormatter(“,”);
Lucene.Net.Highlight.SimpleFragmenter=新的Lucene.Net.Highlight.SimpleFragmenter(50);
//更改为使用query2
Lucene.Net.Highlight.QueryScorer scorer=新的Lucene.Net.Highlight.QueryScorer(query2);
Lucene.Net.Highlight.Highlighter=新的Lucene.Net.Highlighter.Highlighter(格式化程序、记分器);
荧光灯。SetTextFragmenter(fragmenter);
对于(int i=0;i”+highlightedText);
}

如果可以,请让我知道我是否准确地实施了建议。

首先调用QueryParser的

SetMultiTermRewriteMethod(MultiTermQuery.SCORING\u BOOLEAN\u QUERY\u REWRITE)

方法,然后创建一个新查询作为

Query newQuery = query.Rewrite(indexReader);

现在您可以使用“newQuery”进行搜索。

不,这不是巫毒。这个技巧只是通过使用indexreader扩展术语,将多术语查询(如PrefixQuery或RangeQuery)转换为布尔查询。假设索引aaa1和aaa2中有两个术语。像text:aaa*(前缀查询)这样的查询将扩展为(text:aaa1 text:aaa2)。您可以使用query.ToString()函数自己进行测试。感谢您的解释和解决方案。由于像您这样的人提供了惊人的提示,我正在放慢Lucene.NET解决方案的运行速度。干杯,再次感谢。我需要用什么样的indexReader来完成这个重写呼叫?@lurscher,你应该已经有了一个indexReader。您可以通过
newindexsearcher(indexReader)
newindexsearcher(dir)
创建indexSearcher。在这种情况下,您可以通过
searcher.GetIndexReader
Query newQuery = query.Rewrite(indexReader);