Русские документы
Ежедневные компьютерные новости RSS rusdoc.ru  Найти :
Новости
Последние поступления
Книжный магазин
  Hardware:
Видеоустройства
Системные платы
Процессоры
Мобильные устройства
Аудиосистема
Охлаждение системы
Накопители информации
КПК и ноутбуки
Телефоны и связь
Периферия
Система
Сети
Разные устройства
 
  Programming:
Web-разработка
Языки программирования
Технологии и теория
Разработка игр
Программная инженерия
 
  Software:
Операционные системы
Windows 7
Базы данных
Обзоры программ
Графика и дизайн
   
  Life:
Компьютерная жизнь
Разные материалы
   
Партнеры
Публикация
Правовая информация
Реклама на сайте
Обратная связь
Экспорт в RSS Экспорт в RSS2.0
    Читать в Яндекс.Ленте



Интеллектуальный поиск средствами MS SQL Server (2000)

Раздел: Software / MS SQL Server @ 08.07.2008 | Ключевые слова: поиск mssql 2000 русский язык версия для печати

Автор: imhot
Источник: habrahabr

Многие сталкивались с необходимостью реализации интеллектального поиска по базе данных (думаю, что почти все). Тем, кто не нашел подходящего решения или тем, кто просто хотел бы взглянуть на альтернативные решения проблемы, будет полезен следующий код.
Здесь я привожу свою реализацию хранимой процедуры поиска по БД. Возможно, она довольно узкая, т.к. я оптимизировал ее под конкретные задачи и логику. Требования к поисковому запросу таковы, что он может содержать любые символы: кирилицу, цифры, латиницу. спец. символы и т.п.. Итак, код в студию ...


Пусть есть следующая таблица


Create Table [SearchTable]
(
[ID] Int,
[Name] Varchar(350),
[Date] DateTime
)


* This source code was highlighted with Source Code Highlighter.


Напишем для нее процедуру поиска


CREATE PROCEDURE Search
  @Query As Varchar(500)
AS
BEGIN
  /*Будем бить запрос на токены. В данном случае, разделяя по пробелу*/
  Declare @SearchTokens Table
    (
      [Token] Varchar(500)
    );

  /*Временная табличка для результатов. Relevance - будет содержать вес результата*/
  Declare @ResTable Table
    (
      [ID] Int,
      [Name] Varchar(350),
      [Date] DateTime,      
      [Relevance] SmallInt
    );
  
  Declare @CheckStr As Varchar(510);  

  
  Declare @Occurrences As Int;
  Declare @Cnt As Int;
  Declare @tmpStr As Varchar(500);  

  /*Удаляем начальные пробелы*/
  Set @Query = LTrim(@Query);

  /*Концевой символ должен быть пробел*/
  If Substring(@Query, Len(@Query),1) <> ` `
  Begin
    Set @Query = @Query + ` `;
  End;

  /*Сводим все серии пробелов в строке до серий длиной в один символ*/
  While Charindex(` `, @Query) <> 0
  Begin
    Set @Query = Replace(@Query, ` `, ` `);
  End
  
  /*Сколько будет токенов?*/
  Set @Occurrences = Datalength(Replace(@Query, ` `, ` #`)) - Datalength(@Query);  
  Set @tmpStr = @Query;  
  Set @Cnt = 0  
  /*Бьем на токены и заполняем таблицы*/
  While @Cnt <= @Occurrences
  Begin
    Set @Cnt = @Cnt + 1
    /*Берем очередной токен*/
    Set @CheckStr = Substring(@tmpStr, 1, Charindex(` `, @tmpStr) - 1);
    /*Ничего не делаем, если такой уже был*/
    If (SELECT * FROM @SearchTokens WHERE [Token] = @CheckStr) Is Not Null
    Begin
      Continue;
    End
    /*добавляем к токенам*/
    INSERT INTO @SearchTokens VALUES ( @CheckStr );
    /*Небольшое "регулярное выражение". У меня - такое. Вы можете сюда поместить такое, какое необходимо*/
    Set @CheckStr = `%` + @CheckStr + `%`;    
    INSERT INTO @ResTable SELECT S.[ID], S.[Name], S.[Date] 0 FROM [SearchTable] S
            WHERE (S.[Name] LIKE @CheckStr OR
               YEAR ( S.[Date]) LIKE @CheckStr)
              AND NOT (SELECT 1 FROM @ResTable
                      WHERE [ID] = S.[ID]) ="#0000ff">FROM
@SearchTokens WHERE [Token] = @CheckStr) Is Null;
    /*Отрезаем то, что проанализировали*/
    Set @tmpStr = Substring(@tmpStr, Charindex(` `, @tmpStr) + 1, 500)
    If Datalength(@tmpStr) = 0
    Begin
      Break;
    End;
  End;
  
  /*Анализируем данные*/
  Declare Curs Cursor For SELECT * FROM @SearchTokens;
  Declare @Token As Varchar(500);
  Open Curs;
  Fetch Curs Into @Token;
  While @@FETCH_STATUS = 0
  Begin
    UPDATE @ResTable SET [Relevance] = [Relevance] + 1 WHERE [Name] LIKE `%` + @Token + `%`;
    UPDATE @ResTable SET [Relevance] = [Relevance] + 1 WHERE YEAR ( [Date]) LIKE `%` + @Token + `%`;
    Fetch Curs Into @Token;
  End;
  Close Curs;
  Deallocate Curs;
  /*Отдаем результаты упорядочивая по весу */
  SELECT [ID]  , [Name], [Date
    FROM @ResTable ORDER BY [Relevance] DESC;  
END

* This source code was highlighted with Source Code Highlighter.


Послесловие



Вот, пожалуйста. Релизуйте любую логику поиска к любым таблицам или любому количеству связанных таблиц... Все ограничено только фантазией.

Заранее приношу извинения за возможные ошибки в коде, т.к. я урезал имеющуюся процедуру для простоты примера.

UPD: Опять забыл уточнить. Данное решение разработано для MS SQL Server 2000. Для более поздних версий существуют другие, более оптималные решения.

Это интересно:








версия для печатиРаспечатать статью


Вернуться в раздел: Software / MS SQL Server


Реклама:
Читать наc на:

Add to Google
Читать в Яндекс.Ленте






Rambler's Top100
© Copyright 1998-2012 Александр Томов. All rights reserved.