2013-05-29 2 views
5

Мне нужна точная функция поиска, будь то в jquery или C#. Если это возможно, я хочу, чтобы искать, как блестящий, как Google :-)Как создать более точный поиск?

Так вот с # код:

Краткое объяснение:
Этот поиск всех пользователей в базе данных, которая имеет полную информацию. Он выполняет поиск всех пользователей, кроме текущего зарегистрированного пользователя.

string[] ck = keyword.Split(new string[] { " ", ",", "." }, 
          StringSplitOptions.RemoveEmptyEntries); 

using (dbasecore db = ConfigAndResourceComponent.BaseCampContext()) 
{ 
    var results = (from u in db.users 
        join uinfo in db.userinfoes 
         on u.UserID equals uinfo.UserID 
        where u.UserID != userid && 
         (ck.Contains(u.LastName) || ck.Contains(u.FirstName) || 
         ck.Contains(u.MiddleName) || ck.Contains(u.LoginID)) 
        orderby u.LastName, u.FirstName, u.MiddleName ascending 
        select uinfo).Skip(skip).Take(take).ToList(); 

    return (from i in results select new UserInfo(i)).ToList(); 
} 

И результат:

enter image description here

окруженного имя должно быть на верхней части элементов поиска, поскольку он соответствует больше ключевым словам.
Любая идея?

+0

в полном объеме есть ранг, используйте это – vikas

+0

Является вашей колонкой fulltexted – vikas

ответ

1

Для простоты я буду использовать одну таблицу с пользовательским объектом, как это:

public class User 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string MiddleName { get; set; } 
} 

Вот запрос (работает в EF), который вычисляет значение соответствия для каждого пользователя, а затем выбрать только те, которые соответствуют несколько ключевых слов, результаты заказа по значению соответствия:

var keywords = new [] {"Sergey", "Berezovskiy"}; 

var users = from u in context.Users 
      let match = (keywords.Contains(u.FirstName) ? 1 : 0) + 
         (keywords.Contains(u.LastName) ? 1 : 0) + 
         (keywords.Contains(u.MiddleName) ? 1 : 0) 
      where match > 0 
      orderby match descending, 
        u.LastName, u.FirstName 
      select u; 

Диапазона переменной match будет иметь значение от 0 (если ни один полей соответствует ключевым словам) для 3 (если все поля совпадающих).

+1

Я принял это как ответ, потому что это просто и отлично работает. Спасибо за пример. – fiberOptics

0

Ну ... вы сделали укажите конкретный заказ в вашем select. Наверное, это ваш заказ, верно?

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

5

Есть несколько способов, чтобы достичь того, что вы хотите:

1) Написать собственный рейтинг алгоритм. Это означает, что вы получаете результаты с помощью Linq, а затем сортируете их с помощью собственной функции ранжирования - что может быть чем-то простым, например, расщепляющим запрос в слова и подсчетом появления этих слов в каждом результате или чем-то сложным, например, используя поиск для поиска различных форм запроса термины, измеряя расстояние между терминами, увеличивая некоторые термины и т. д. Я бы не стал рекомендовать идти этим путем - потому что запросы Like медленны на SQL, и вам нужно написать что-то, что уже написано.

2) Использовать полный поиск по Sql-серверу: http://msdn.microsoft.com/en-us/library/ms142524(v=sql.105).aspx. Хотя я не поклонник полнотекстового поиска SQL Server, это хорошее и жизнеспособное решение.

3) Использование стороннего полнотекстового поиска, есть несколько альтернатив, Lucene (http://www.codeproject.com/Articles/29755/Introducing-Lucene-Net), вероятно, наиболее часто используется в .net. Это дает вам скорость и гибкость, вы можете индексировать свои данные по-разному, но, несомненно, вы будете реагировать на их индексирование. Там также есть API поверх Lucene, как Solr, которого я люблю больше всего - хотя это может быть слишком много в вашем случае.

1

Как блестяще, поскольку Google может быть далеким, но вы можете достичь чего-то приемлемого, используя очень простую технику. Вот идея:

В вашем предложении WHERE вместо выполнения WHERE ck.Contains(u.LastName) || ck.Contains(u.FirstName) вы можете добавить выражение, которое присваивает значение каждому успешному критерию (в соответствии с его относительным весом) и добавляет их для получения окончательного результата. Например:

WHERE (ck.Contains(u.LastName)? 1 : 0) + (ck.Contains(u.FirstName)? 2 : 0) + ... 

Не уверен, что если LINQ поддерживает тройной оператор или нет, но если это не вы можете достичь того же с помощью цикла и ручной метод тоже. Сумма всех условий даст более высокую оценку кандидатам, которые являются более близкими. Затем вы можете отсортировать этот столбец.

Смежные вопросы