Я использую Umbraco 7.9.0, Examine 0.1.89 и Lucene.Net 2.9.4.1 (+ Lucene.Net.Contrib). Я хочу выполнить поиск по полной фразе (например, «тарифы на звонки») и выделить ее вконкретное поле. (полная фраза, а не 1 слово) Как я могу правильно ее реализовать?
Я использую этот код для выделения, но в некоторых случаях он может выделять только 1 слово вместо 2.
public static SearchResult HighlightResults(this SearchResult result, Query query, string[] fieldsToHighlight)
{
var scorer = new QueryScorer(query);
var formatter = new SimpleHTMLFormatter("<b>", "</b>");
var highlighter = new Highlighter(formatter, scorer);
highlighter.SetTextFragmenter(new SimpleFragmenter());
foreach (var fieldToHighlight in fieldsToHighlight)
{
if (!result.Fields.ContainsKey(fieldToHighlight)) continue;
string fieldValue = result[fieldToHighlight];
var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29, new System.Collections.Hashtable() { { "1", "1" } });
var fragments = highlighter.GetBestFragments(analyzer, fieldValue, 300);
string highlightedFieldValue = string.Join(" ", fragments);
if (!String.IsNullOrWhiteSpace(highlightedFieldValue))
{
result.Fields[fieldToHighlight] = highlightedFieldValue;
}
}
return result;
}
Мой код для поиска:
var sFields = new string[]
{
"pageTitle",
"summary",
"report",
"keywords"
};
if (!string.IsNullOrWhiteSpace(term))
{
var sc = this.CompltetedOnlySearchQuery(BooleanOperation.And);
var phrases = ContentHelper.GetAcronymsList(term);
var queries = new List<IExamineValue>();
phrases.Add(term);
foreach (var phrase in phrases)
{
foreach (var searchField in sFields)
{
var boostValue = 1f;
switch (searchField)
{
case "report":
case "summary":
boostValue = 100f;
break;
case "pageTitle":
boostValue = 50f;
break;
}
queries.Add(phrase.Boost(boostValue));
}
}
sc = sc.And()
.GroupedOr(sFields, queries.ToArray());
var results2 = this.searcher.Search(sc.Compile());
var criteria = sc.Compile() as LuceneSearchCriteria;
var fieldsToHighlight = new string[] { CommonPropertyAliasConstants.Content };
results = this.searcher.Search(sc.Compile())
.Select(x => new CaseSearchResult(x.HighlightResults(criteria.Query, fieldsToHighlight))).OrderByDescending(x => x.Order).ToList();
}
private IBooleanOperation CompltetedOnlySearchQuery(BooleanOperation @operator) =>
this.searcher.CreateSearchCriteria(@operator).Field("Completed", "1");