регистрация | карта сайта
Постоянно обновляемая лента новостей
Обзоры, комментарии и статьи
Даты и дополнительная информация о событиях компьютерного рынка
Контакты, виды деятельности, предложения и другая информация о компьютерных компаниях
Новости, анонсы и пресс-релизы компьютерных компаний
Конференции с участием ведущих специалистов и экспертов
Информация для пользователей ITware, изменения персональных настроек, персональные закладки и web-карточки, служба переадресации
   
    
     Как искать?   Расширенный поиск
 ITware :. Конкурс статей Borland      Вход для зарегистрированных пользователейВыход

Конкурс статей Borland
Главная страница
Правила участия
Общий рейтинг
Призовой фонд
Сообщество ITware

Логин:
Пароль:
Забыли пароль? Забыли логин?

Зарегистрируйтесь сейчас - это абсолютно бесплатно!
Подпишитесь на рассылку ITware, чтобы ежедневно получать анонсы последних новостей и свежих материалов


CHIP online
Best Buy
Посоветуйся с Чипом!
Downloads

Контакты
Редакция:

Web-мастер:

 
Реклама




Ох уж эти мне слова
29 мая 2003 16:05  rollback количество баллов: 13

Времена, когда объемы ежедневной почтовой корреспонденции в нашей организации исчислялись килобайтами, давно ушли в прошлое. Лет 5-ть назад количество корреспонденции начало стремительно возрастать. Появилась заархивированная различными архиваторами корреспонденция в разных форматах: Ms Word/Excel, html, eml. Когда объем, совершенно разнородной, корреспонденции начал приближаться к гигабайту в год, я принял решение о написании программного обеспечения, для систематизации этого информационного потока. Основной головной болью стал поиск архивных документов содержащих номер письма или какую-то ключевую фразу. Очень редко было известно точное название файла. Нужно было создавать программу с возможностью контекстного поиска. То есть по какому-то слову или его части.
Вариант хранение всего текста в базе данных отпал сразу. Оперировать гигабайтами текста очень накладно. Пусть уж лучше файлы, хранятся там, где им положено . на жестком диске. А в базу поместим только слова и то, в каких файлах они встречаются. Каждый файл получает как бы инвентаризационную карточку. В русском языке слов около 30-ти тысяч, а большинство из них редко употребляемые. Даже если добавить украинские и английские слова, то все равно получим таблицу, с которой управится среднего веса СУБД. Подобную обработку текстов программисты часто называют индексацией, а для пользователей контекстным поиском.
Так как задача в основном ясна, перейдем к практической части. Заранее хочу предупредить читателей, что описана только принципиальная часть процедуры индексации слов в файлах, а структура данных максимально упрощена. Не в ущерб, надеюсь, пониманию вопроса.
Программа разрабатывалась в среде Borland Delphi 3. Это была последняя на тот момент версия. Позже ПО было переработано в Delphi 5. СУБД была избрана Sybase SQL Anywhere 5, так как это основной SQL сервер фирмы. Однако перенести ПО на другие СУБД довольно просто, если не считать проблем с синтаксисом запросов. Индексация файлов в СУБД построена на 4-х таблицах:

1. Таблица встреченных программой слов [<b>words</b>].

<b>CREATE TABLE "DBA"."words"
(
"ID" integer NOT NULL DEFAULT autoincrement,
"word" char(20) NOT NULL,
PRIMARY KEY ("ID")
)</b>

И индекс по базе слов

<b>CREATE UNIQUE INDEX "words_index" ON "DBA"."words"
(
"word" ASC
)</b>

Сюда программа запоминает все встреченные ею слова при индексации файлов. Вы можете добавить свои поля в эту таблицу, например количество цифр в слове. Однако помните, что нагрузка на эту таблицу, а особенно индекс [words_index] будет, пожалуй, самой сильной. Если Ваша СУБД позволяет, то размещайте ее на самом быстром пространстве сервера.


2. Таблица обработанных файлов .<b>Files</b>.
<b>
CREATE TABLE "DBA"."files"
(
"ID" integer NOT NULL DEFAULT autoincrement,
"FilePath" char(255) NOT NULL,
PRIMARY KEY ("ID")
)</b>

В эту таблицу заносятся все обработанные программой файлы. Я показал самое минимальное описание такой таблицы. На практике надо добавить разные вспомогательные поля: дата создания файла, короткое имя, тип файла и.т.д в зависимости от того, какую функциональность Вы хотите придать вашей программе. Размер данной таблицы будет расти постоянно, это будет самая объемная таблица.

3. Таблица наличия в файле определенных слов [<b>Links</b>]

<b>CREATE TABLE "DBA"."links"
(
"ID" integer NOT NULL DEFAULT autoincrement,
"FileID" integer NOT NULL,
"WordID" integer NOT NULL,
PRIMARY KEY ("ID")
)</b>
и два индекса
<b>
CREATE INDEX "words_id" ON "DBA"."links"
(
"WordID" ASC
)</b>
и
<b>
CREATE INDEX "files_id" ON "DBA"."links"
(
"FileID" ASC
)
</b>

В этой таблице для каждого файла указывается код встреченных в нем слов. Так, к примеру, если в некотором файле c кодом 52 (поле ID таблицы files) есть слово Borland с кодом 258 (поле ID таблицы words) то в базу будут занесена следующая информация:

<b>
Insert into dba.links values
(
default, 52, 258
)</b>

Заносятся только ключевые поля таблиц Files и Words, а не текст или полная информация о файле. Это позволяет уменьшить объем таблицы. Да и оперировать с числами СУБД намного легче, чем с текстом. Надо заметить, что таблице links будет довольно много записей. Количество можно оценить умножив количество проиндексированных файлов на количество уникальных слов в них.
Построив нашу базу данных . приступим непосредственно к индексации.
1. Получаем текстовое содержимое файла. Я, к сожалению, не могу здесь описать получение текста с файлов разных форматов. MS Word, к примеру, лучше всего вычитывать ч-з OLE Automatic.
2. Разбиваем текс на слова. Алгоритм за вами. Я, к примеру, использовал две функции библиотеки RxLIB

<b>function WordCount(const S: string; const WordDelims: TCharSet): Integer; </b>- возвращает количество слов в строке. Разделители слов (пробелы, запятые и.т.д.) указываем в множестве WordDelims.
<b>function ExtractWord(N: Integer; const S: string; const WordDelims: TCharSet): string; </b>- возвращает слово ≤ N строки S согласно множеству разделителей слов WordDelims.

Вполне допускаю, что есть и более быстрые алгоритмы определения отдельных слов.
3. Ищем слово из индексируемого файла в таблице words. Если оно отсутствует, то заносим в таблицу. Узнаем код слова (поле ID таблицы words).
4. По таблице links проверяем, не включали ли мы раньше связку код файла и код слова, задав, например такой запрос select * from dba.links where FileID=.код файла. and WordID =.код слова.. Если отсутствует, то записываем в базу.
Проделав такую же процедуру для всех слов файла, мы его проиндексируем.
Как же осуществить контекстный поиск по этой базе? Да запросто. Припустим, мы ищем файлы, в которых есть слово Borland. Тогда запросом на нашу базу данных:

<b>
select L.FileID,f. FilePath
from branch.link as l,branch.Files as f
where wordID in (select id from branch.words where word=.Borland.) and f.ID=l.FileID
</b>

мы получим список всех искомых файлов. Для мягкого поиска, по части слова, запрос модифицируется следующим образом:

<b>
select L.FileID,f. FilePath
from branch.link as l,branch.Files as f
where wordID in (select id from branch.words where word like.%Borland%.) and f.ID=l.FileID
</b>

Вот и все, что я хотел вам рассказать. Более чем уверен, что есть другие и, наверное, лучшие способы искать слова в безразмерном информационном потоке. Но свое начинание, как известно, "ближе к телу". Если кому-то подойдет этот способ, то пользуйтесь на здоровье. В последнее время в операционные системы начали встраивать подобные службы индексации. Однако их сложно приспособить под специфику работы конкретной фирмы. Так, кроме простого поиска файла, часто надо знать информацию о том кто в последний раз обрабатывал файл, кем он распечатан, до кого доведен. Тут уж без своей программы не обойтись.
Успехов в поисках. <i>Искренне ваш . RollBack</i>



Статьи данного автора в акции Borland:
Обсуждение
30 августа 2003 - 08:02 aeff конструктив
Как подметил Rollback в комментариях к статье ╚Методика разработки программного обеспечения в среде Delphi для систем промышленной автоматизации╩, особенностью конкурса на itware есть то, что в статье позволено размещать только одну картинку и то в конце статьи, а я вижу 2 статьи, к которым это не относится. У нас, есть черные и белые люди? Это же не честно. Предлагаю исключить из конкурса статьи, у которых больше одного рисунка. ИМХО это будет справедливо.
Новое сообщение
Логин:
Пароль:
Заголовок:
Сообщение:

© ICC. Перепечатка допускается
только с разрешения .
Новости Публикации Календарь событий Пресс-центр
IT-каталог: продукты IT-каталог: компании Библиотека
Форум Персональные сервисы Регистрация Карта сайта
Звуки му последнее представление в киеве