自己动手写分布式搜索引擎
上QQ阅读APP看书,第一时间看更新

2.1 构 建 索 引

为了按词建立索引,需要对文档分词。把这个分词类叫作Analyzer。文档内容作为输入流Reader的实例传入。

        public class Analyzer {
            String[] split(Reader reader) {
                //对文档内容分词,并返回分词后的词数组
            }
        }

首先建立文档索引,也就是正排索引,然后建立倒排索引。

正排索引用到的DocConsumer类如下。

        public class DocConsumer {
            public int docid; //文档编号
            //词到频率的映射,频率存在长度是1的整数数组中
            HashMap<String, int[]> frequencyList;
            int words;  //文档长度,也就是这个文档包含多少个词
        }

然后建立倒排索引。倒排索引用到的Posting类如下。

        public class Posting implements Serializable {
            public int docid; //文档编号
            public int freq; //这个词在文档中出现了多少次
            Posting(int doc, int freq) {
                this.docid = doc;
                this.freq = freq;
            }
        }

这里把文档作为一个字符串,如果有多列,可以把文档作为一个自定义的对象。

        public class Document {
                public String title; //标题列
                public String content; //内容列
        }

为了更灵活地定义文档的结构,可以专门定义一个Field类。

        public class Field {
          /** 列名  */
          public final String name;


          /** 列值 */
          public String fieldsData;
        }

一个Document类的实例中可以包含多个Field类的实例。

在真正的信息检索中,都是有多个列的,而且很多列有同等重要的地位。对于多个列的检索,简单的方法是:给每个倒排列附加一个bit-map,假设有N列,则Bitmap长度是N。例如,title出现,则第1位为1, content没出现,则第2位为0。实际的做法是:把一个列中所有的词连续存放到一起,一个专门的列定义文件中包括某个列中这些词信息的开始位置,如图2-2所示。

图2-2 多列索引