Диапазон запросов Lucene.net + выделение
Еще один вопрос 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 AND date:[1286273266 TO 32503680000]
Когда это запрашивается, он находит все результаты для "сумасшедших", но не выводит никакого выделенного текста.
Когда диапазон дат будет удален и вы просто запросите термин:
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);
}
Если вы могли бы, дайте мне знать, если я точно выполнил предложения.
1 ответ
Сначала вызовите QueryParser's
SetMultiTermRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE)
метод, а затем создать новый запрос как
Query newQuery = query.Rewrite(indexReader);
Теперь вы можете использовать "newQuery" для поиска.