#c# #nhibernate #search #ranking
#c# #nhibernate #Поиск #Рейтинг
Вопрос:
У меня есть постраничный список результатов поиска. Пользователь может выполнить поиск по ‘derp’, и возвращается все, что содержит эту последовательность символов в любом месте имени.
Меня попросили изменить это, чтобы этот набор результатов изначально был ранжирован по релевантности. Итак, если обычно список будет возвращен как
a derp abc // everything is alphabetical
a derp xyz
b derp abc
derp abc
derp def
herp derp a
herp derp b
теперь список необходимо отсортировать как
derp abc // these guys are given prominence
derp def
a derp abc // the rest of results alphabetical as normal
a derp xyz
b derp abc
herp derp a
herp derp b
имея в виду, что этот список должен быть разбит на страницы (т. Е. я не могу просто взять результат поиска и вручную удалить вхождения ‘derp’ из середины и переместить их вперед), есть ли какой-либо способ с помощью NHibernate указать требуемый рейтинг?
Или я должен выполнить 2 запроса, первый из которых ищет что-либо, начинающееся с ‘derp’, а второй, который содержит ‘derp’, но не начинается с него?
Ответ №1:
OrderBy может использовать проекции, так что это будет работать просто отлично:
var list = session.QueryOver<Store>()
.Where(s => s.Name.IsLike("My", MatchMode.Anywhere))
.OrderBy(NHibernate.Criterion.Projections.Conditional(
NHibernate.Criterion.Restrictions.Like(
NHibernate.Criterion.Projections.Property<Store>(s => s.Name), "My",
MatchMode.Start),
NHibernate.Criterion.Projections.Constant(0),
NHibernate.Criterion.Projections.Constant(1))).Asc
.ThenBy(s => s.Name).Asc
.List();
Что мы здесь делаем, так это используем проекцию, которая в основном преобразуется в следующий SQL:
ORDER BY (case when this_.Name like 'My%' then 0 else 1 end)