Я пытаюсь настроить lucene.net 3, чтобы иметь возможность искать по двум полям для фразы, и я застреваю. Вот что я хотел бы для запроса, чтобы вернуться:MultiFieldQueryParser и подстановочные знаки
Я хочу, чтобы запрос, чтобы вернуть точную фразу соответствует как:
фраза: «CHING WAN HUNG SOOTHING ТРАВЯНОЙ БАЛЬЗАМ»
результат: «CHING WAN HUNG SOOTHING ТРАВЯНОЙ БАЛЬЗАМ»
Как спички Wildcard:
фраза: "CHING WAN HUNG СОО" ИЛИ "CHING WAN HUN"
результат: «CHING WAN HUNG SOOTHING HERBAL BALM» и другие, которые могут соответствовать этому или любому другому неполному варианту фразы.
Мое первоначальное решение состояло в том, чтобы создать логический запрос с фразерой и запросом, который анализирует и подталкивает каждое слово.
Но это возвращает матч, а также слишком много результатов, которые не близки к применимости. (Он вернет «HERBAL TEA», так как «HERBAL» является одним из разобранных терминов ...) Из-за анализируемого запроса OR.
Это связано с оригинальным сообщением, которое у меня было: How to set up a query to return phrases and parts of phrases in lucene.net? Было интересно, могу ли я сделать это в стандартном Lucene.net, не обращаясь к упомянутому порту Java.
Может ли кто-нибудь дать мне какие-либо рекомендации по этому поводу? Спасибо!
public override List<TT> ExecuteSearch(string searchQuery, string searchField = "")
{
if (string.IsNullOrEmpty(searchQuery.Replace("*", "").Replace("?", ""))) return new List<TT>();
using (var searcher = new IndexSearcher(Directory, false))
{
var hits_limit = 1000;
var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30, new HashSet<string>());
var fields = new[] {"CompositeName", "SubstanceName"};
var parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, fields, analyzer);
parser.AllowLeadingWildcard = true;
parser.PhraseSlop = 0;
var query = ParseWholeQueryWc(searchQuery, fields, parser);
searcher.SetDefaultFieldSortScoring(true, true);
var hits = searcher.Search(query, null, hits_limit, Sort.RELEVANCE).ScoreDocs;
var results = MapLuceneToDataList(hits, searcher);
analyzer.Close();
searcher.Dispose();
return results;
}
}
public Query ParseWholeQueryWc(string searchQuery, string[] fields, QueryParser parser)
{
Query query = new PhraseQuery();
Query query2 = new PhraseQuery();
Query mq = new BooleanQuery();
try
{
var bld = ParseTermWithWildcards(searchQuery);
// phrase
query = parser.Parse("\"" + searchQuery.Trim() + "\"");
// or
query2 = parser.Parse(searchQuery + "*");
// main
((BooleanQuery)mq).Add(query, Occur.SHOULD);
((BooleanQuery)mq).Add(query2, Occur.SHOULD);
}
catch (ParseException ex)
{
throw;
}
return mq;
}
UPDATE
public BooleanQuery ParseWholeQueryWc(string searchQuery, string[] fields, QueryParser parser)
{
BooleanQuery mq = new BooleanQuery();
try
{
string[] qrArr = searchQuery.Split(null);
SpanQuery[] compNmQ = new SpanQuery[qrArr.Length];
SpanQuery[] subsNmQ = new SpanQuery[qrArr.Length];
for (var i = 0; i < qrArr.Length; i++)
{
//CompositeName", "SubstanceName
if (i == qrArr.Length - 1)
{
compNmQ[i] = new SpanTermQuery(new Term("CompositeName", qrArr[i] + "*"));
subsNmQ[i] = new SpanTermQuery(new Term("SubstanceName", qrArr[i] + "*"));
}
else
{
compNmQ[i] = new SpanTermQuery(new Term("CompositeName", qrArr[i]));
subsNmQ[i] = new SpanTermQuery(new Term("SubstanceName", qrArr[i]));
}
}
SpanQuery compNameQ = new SpanNearQuery(compNmQ, 0, true);
SpanQuery subsNameQ = new SpanNearQuery(subsNmQ, 0, true);
// main
((BooleanQuery) mq).Add(compNameQ, Occur.SHOULD);
((BooleanQuery)mq).Add(subsNameQ, Occur.SHOULD);
}
catch (ParseException ex)
{
throw new ArgumentException("BaseLuceneStrategy:ParseWholeQueryWc():" + ex.Message);
}
return mq;
}
Это теперь будет возвращать ноль хитов.
Спасибо femtoRgon, я создал это и теперь возвращает нулевые записи. Я добавил свой модифицированный код по вашему предложению выше в своем оригинальном посте. – melmack
Возможно, из-за анализа. Имейте в виду, что анализаторы здесь не будут применяться. Похоже, вы используете StandardAnalyzer, который уменьшает все, поэтому вам нужно будет очертить условия поиска. – femtoRgon
Я топнул струну, и она работает хорошо. Только дело в том, что он получает нулевые удары, когда я пытаюсь найти «CHING WAN HUNG SOOTHING HERBAL BA» или «CHING WAN HUNG SOOTHING HERBAL BAL». Любая идея почему? Еще раз спасибо за ответ. – melmack