База данных поиска - ASP.NET MVC C # - PullRequest
2 голосов
/ 03 октября 2009

Я пытаюсь реализовать полную функциональность поиска на моем веб-сайте ASP.NET MVC (C #, Linq-to-Sql).

Сайт состоит из 3-4 таблиц, в которых есть 1-2 столбца, которые я хочу найти.

Это то, что я имею до сих пор:

    public List<SearchResult> Search(string Keywords)
    {
        string[] split = Keywords.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
        List<SearchResult> ret = new List<SearchResult>();
        foreach (string s in split)
        {
            IEnumerable<BlogPost> results = db.BlogPosts.Where(x => x.Text.Contains(s) || x.Title.Contains(s));

            foreach (BlogPost p in results)
            {
                if (ret.Exists(x => x.PostID == p.PostID))
                    continue;

                ret.Add(new SearchResult
                {
                    PostTitle= p.Title,
                    BlogPostID = p.BlogPostID,
                    Text=p.Text
                });

            }
        }
        return ret;
    }

Как видите, у меня есть foreach для ключевых слов и внутренний foreach, который работает над таблицей (я бы повторил это для каждой таблицы).

Это кажется неэффективным, и я хотел знать, есть ли лучший способ создать метод поиска для базы данных.

Кроме того, что я могу сделать со столбцами в базе данных, чтобы их можно было искать быстрее? Я что-то читал об их индексации, это просто поле «Полнотекстовая индексация» True / False, которое я вижу в SQL Management Studio?

Ответы [ 2 ]

6 голосов
/ 05 октября 2009

Кроме того, что я могу сделать с колонками в база данных, чтобы они могли быть искали быстрее? Я читаю что-то о индексации их, это только Поле «Полнотекстовая индексация» True / False Я вижу в SQL Management Studio?

Да, включение полнотекстовой индексации обычно имеет большое значение для повышения производительности в этом сценарии. Но, к сожалению, он не работает автоматически с оператором LIKE (и именно это генерирует ваш запрос LINQ). Поэтому вам придется использовать одну из встроенных функций полнотекстового поиска, таких как FREETEXT, FREETEXTTABLE, CONTAINS или CONTAINSTABLE.

Просто для пояснения, ваш исходный код будет значительно медленнее, чем полнотекстовый поиск, поскольку обычно он приводит к сканированию таблицы. Например, если вы ищете поле varchar с именем title с помощью LIKE "% ABC%", то у SQL нет другого выбора, кроме как сканировать каждую запись, чтобы определить, содержит ли она эти символы.

Однако встроенный полнотекстовый поиск будет фактически индексировать текст каждого столбца, который вы указали для включения в полнотекстовый индекс. И именно этот индекс значительно ускоряет ваши запросы.

Мало того, полнотекстовый поиск предоставляет некоторые интересные функции, которые оператор LIKE не может вам предоставить. Это не так сложно, как Google, но у него есть возможность поиска альтернативных версий корневого слова. Но одна из моих любимых функций - это функция ранжирования, где она может возвращать дополнительное значение, чтобы указать релевантность, которую затем можно использовать для сортировки результатов. Чтобы использовать это, посмотрите на функции FREETEXTTABLE или CONTAINSTABLE .

Еще несколько ресурсов:

0 голосов
/ 03 октября 2009

Следующее должно сделать трюк. Я не могу сказать, изо всех сил, будет ли на самом деле работать let kwa = ... часть, но что-то подобное потребуется, чтобы сделать массив ключевых слов доступным в контексте SQL Сервер. Некоторое время я не использовал LINQ to SQL (уже некоторое время я использую LINQ to Entities 4.0 и nHibernate, которые обладают другим набором возможностей). Возможно, вам придется настроить эту часть, чтобы она заработала, но общий принцип звучит правильно:

public List<SearchResult> Search(string keywords)
{    
  var searcResults = from bp in db.BlogPosts
                     let kwa = keywords.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);
                     where kwa.Any(kw => bp.Text.Contains(kw) || bp.Title.Contains(kw))
                     select new SearchResult
                     {
                        PostTitle = bp.Title,
                        BlogPostID = bp.BlogPostID,
                        Test = bp.Text
                     };

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