Как упорядочить результаты запроса сначала по поисковому запросу, а затем по алфавиту? - PullRequest
4 голосов
/ 07 июня 2011

Я использую NHibernate для поиска по имени элемента. Я получаю постраничный список элементов из базы данных и упорядочиваю его по возрастанию имени элемента.

Итак, если я ищу «термин», я получаю страницу результатов, которая содержит «термин» в любом месте результата, и страница упорядочена в алфавитном порядке.

Например, результаты могут выглядеть следующим образом

a term
d term
g term
j term
p term
s term
term 1
term 2
v term    
z term

Технически этот список правильный, потому что он упорядочен по алфавиту.

Однако технически правильного недостаточно для клиента. Они хотят, чтобы список упорядочивался сначала по релевантности искомого термина, а затем по алфавиту.

Таким образом, результат станет

term 1
term 2
a term
d term
g term
j term
p term
s term
v term    
z term

Я не знаю, как сконструировать этот запрос, или если это вообще возможно. Если бы это можно было сделать в приложении, это было бы намного проще, но из-за подкачки это должно быть сделано в базе данных. Это то, что усложняет вещи. Может ли кто-нибудь, пожалуйста, указать мне правильное направление здесь?

Ответы [ 3 ]

2 голосов
/ 07 июня 2011

Я никогда не видел ничего более сложного в SQL или Linq для поиска по «релевантности».

Если бы это была моя проблема, я бы попытался создать настраиваемый вспомогательный класс, который реализует IComparer. Затем вы можете создать любое количество нюансов в коде. Конечно, это не сделано на стороне сервера.

Интересно, существует ли сторонняя библиотека .net, которая могла бы конкретно определить релевантность.

1 голос
/ 07 июня 2011

Благодаря предложению Рэя я реализую следующее:

CREATE FUNCTION [dbo].[fnGetRelevance] 
(   
    @fieldName nvarchar(50),
    @searchTerm nvarchar(50)
)

RETURNS  int
AS
BEGIN
    if (@fieldName like @searchTerm + '%') -- starts with
    begin       
        return 0
    end
    else if ((@fieldName like '%' + @searchTerm + '%') and (@fieldName not like @searchTerm + '%')) -- contains, but doesn't start with 
    begin       
        return 1
    end

    return 1
END

GO

Это привело к следующему снижению производительности для 1 из более крупных запросов:

enter image description here

1 голос
/ 07 июня 2011

Если возможно написать функцию, которая возвращает целое число в зависимости от релевантности, вы можете сделать

SELECT MyField
FROM MyTable
WHERE MyField like '%term%'
ORDER BY GetRelevance(MyField, SearchTerm) DESC

Ваша функция не должна быть очень сложной. Можно просто посмотреть, начинается ли поле с SearchTerm и возвращает 2, а если нет - 1. Затем вы можете расширить его, если у вас есть больше критериев релевантности.

Или, если под релевантностью вы подразумеваете, что он начинается с поискового запроса, вы также можете разбить ваш запрос БД на два и объединить их вместе.

т.е.

SELECT MyField
FROM MyTable
WHERE MyField LIKE 'term%' 
ORDER by MyField

union
SELECT MyField
FROM MyTable
WHERE MyField LIKE '%term%' AND NOT LIKE 'term%'
ORDER BY MyField

Это не будет хорошо для вашего выступления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...