Как указать рейтинг для результатов поиска NHibernate, основанный на местоположении поискового запроса в результатах?

#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)