在C#中为信息检索应用程序编写反向索引

时间:2010-01-21 15:01:01

标签: c# search data-structures full-text-search

我正在编写一个内部应用程序,其中包含多条文本信息以及有关这些文本的大量数据。这些数据将按入口顺序保存在数据库(SQL Server,尽管可能会更改)中。

我希望能够搜索这些信息中最相关的信息,其中最相关的信息位于顶部。我最初考虑使用SQL Server全文搜索,但它不像我希望的那样灵活满足我的其他需求,因此我似乎需要为此开发自己的解决方案。

根据我的理解,我需要的是inverted index,然后根据所保存的附加信息的结果恢复和修改所述倒排索引的内容(尽管现在可以留给以后的日期因为我只想让倒排索引从提供的数据库表/字符串中索引主文本)。

我在使用Hashtable在Java中编写此代码时遇到了一个问题,其中密钥作为单词,值作为单词出现的列表但是老实说我仍然是C#的新手并拥有在处理信息时,才真正使用DataSet和DataTables之类的东西。如果我要求,一旦我清除了这台病毒笔记本,我就会立即上传Java代码。

如果从表或字符串列表中给出一组条目,那么如何在C#中创建一个反向索引,最好保存到DataSet / DataTable中?

编辑:我忘了提到我已经尝试过Lucene和Nutch,但是需要我自己的解决方案,因为修改Lucene以满足我的需求需要比编写倒置索引要长得多。我将处理大量的元数据,这些元数据在基本的反向索引完成后也需要处理,所以我现在需要的是使用反向索引在一个区域上进行基本的全文搜索。最后,制作倒排索引并不是我每天都要做的事情,所以对它进行破解是很好的。

3 个答案:

答案 0 :(得分:5)

以下是我过去在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()和char字符类型检查方法(IsAlpha等)。

GetDatabaseTextFieldForID()和GetDatabaseFieldIDS()是不言自明的,可根据需要实现。

答案 1 :(得分:2)

Lucene.net可能是您最好的选择。它是一个使用inverted indexes的成熟全文搜索引擎。

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

更新:

我使用Lucene.net编写了一个用于索引内存中集合的小库 - 它可能对此有用。 https://github.com/mcintyre321/Linqdex

答案 2 :(得分:1)

如果您想要自己创建,Dictionary<T>类很可能是您的基础,就像您的Java哈希表一样。对于存储为字典中的值的内容,根据您提供的信息很难判断,但通常搜索算法使用某种类型的Set结构,因此您可以运行联合和交叉。 LINQ在任何IEnumerable上为您提供了大部分功能,尽管专门的Set类可以提高性能。

集合的一个这样的实现在Wintellect PowerCollections中。我不确定这是否会给你带来任何性能上的好处,而不是LINQ。

至于保存到DataSet,我不确定你想要的是什么。我不知道任何“自动”写入DataSet的内容。我怀疑你必须自己写这个,特别是因为你多次提到其他第三方选项不够灵活。