Написание инвертированного индекса на C # для приложения для поиска информации - PullRequest
8 голосов
/ 21 января 2010

Я пишу собственное приложение, которое содержит несколько фрагментов текстовой информации, а также ряд фрагментов данных об этих фрагментах текста. Эти фрагменты данных будут храниться в базе данных (SQL Server, хотя это может измениться) в порядке ввода.

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

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

У меня была проблема с написанием этого кода на Java с использованием Hashtable с ключом в качестве слов и значением в виде списка вхождений слова, но, честно говоря, я все еще новичок в C # и имею только реально используемые вещи, как DataSets и DataTables, при обработке информации. Если потребуется, я скоро загрузлю код Java, как только очистил этот ноутбук от вирусов.

Если задан набор записей из таблицы или из списка строк, как можно создать инвертированный индекс в C #, который предпочтительно будет сохранять в DataSet / DataTable?

РЕДАКТИРОВАТЬ: Я забыл упомянуть, что я уже пробовал Lucene и Nutch, но мне нужно мое собственное решение, так как изменение Lucene для удовлетворения моих потребностей займет гораздо больше времени, чем написание перевернутого индекса. Я буду обрабатывать много метаданных, которые также потребуют обработки, как только базовый инвертированный индекс будет завершен, поэтому все, что мне сейчас нужно, - это базовый полнотекстовый поиск в одной области с использованием инвертированного индекса. Наконец, работа с инвертированным индексом - это не то, чем я занимаюсь каждый день, так что было бы замечательно иметь на это трещину.

Ответы [ 3 ]

5 голосов
/ 21 января 2010

Вот краткий обзор подхода, который я успешно использовал в C # в прошлом:

 struct WordInfo
 {
     public int position;
     public int fieldID;
 }

 Dictionary<string,List<WordInfo>> invertedIndex=new Dictionary<string,List<WordInfo>>();

       public void BuildIndex()
       {
            foreach (int  fieldID in GetDatabaseFieldIDS())
            {    
                string textField=GetDatabaseTextFieldForID(fieldID);

                string word;

                int position=0;

                while(GetNextWord(textField,out word,ref position)==true)
                {
                     WordInfo wi=new WordInfo();

                     if (invertedIndex.TryGetValue(word,out wi)==false)
                     {
                         invertedIndex.Add(word,new List<WordInfo>());
                     }

                     wi.Position=position;
                     wi.fieldID=fieldID;
                     invertedIndex[word].Add(wi);

                }

            }
        }

Примечания:

GetNextWord () выполняет итерацию по полю и возвращает следующее слово и позицию. Для реализации этого взгляните на использование string.IndexOf () и методов проверки типа символов (IsAlpha и т. Д.).

GetDatabaseTextFieldForID () и GetDatabaseFieldIDS () говорят сами за себя, реализуют по мере необходимости.

2 голосов
/ 21 января 2010

Lucene.net может быть вашим лучшим выбором. Это зрелая полнотекстовая поисковая система, использующая инвертированные индексы .

http://codeclimber.net.nz/archive/2009/09/02/lucene.net-your-first-application.aspx

UPDATE:

Я написал небольшую библиотеку для индексации коллекций в памяти с помощью Lucene.net - это может быть полезно для этого. https://github.com/mcintyre321/Linqdex

1 голос
/ 21 января 2010

Если вы хотите раскрутить свой собственный класс, то, скорее всего, класс Dictionary<T> станет вашей базой, как ваши хеш-таблицы Java. Что касается того, что хранится в виде значений в словаре, трудно сказать, основываясь на информации, которую вы предоставляете, но обычно алгоритмы поиска используют некоторый тип структуры Set, чтобы вы могли запускать объединения и пересечения. LINQ предоставляет вам большую часть этой функциональности для любого IEnumerable, хотя специализированный класс Set может повысить производительность.

Одна из таких реализаций набора находится в Wintellect PowerCollections . Я не уверен, что это даст вам какой-либо выигрыш в производительности по сравнению с LINQ.

Что касается сохранения в DataSet, я не уверен, что вы предполагаете. Я не знаю ничего, что «автоматически» пишет в DataSet. Я подозреваю, что вам придется написать это самостоятельно, тем более что вы несколько раз упоминали о том, что другие сторонние варианты недостаточно гибки.

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