Java API 文档搜索引擎项目详解

项目背景
Oracle 官网虽然提供了 Java API 文档, 但是并没有提供搜索模块, 只是将这些 API 按字典序排序了, 这导致要查询 API 的时候十分麻烦, 因而这个项目就诞生了.
项目介绍
用户输入一个查询词, 服务器会返回与查询词相关的若干条结果, 每个结果都由 标题, 文档描述, 展示 URL 组成, 点击标题即可跳转到对应结果的网页.
项目开发

  • 索引模块

    首先去 Oracle 官网下载 Java API 文档到本地, 然后根据这些 API 建立起正排索引和倒排索引. 正排索引是一个顺序表的结构, 每一个元素由 文档 id, 文档标题, 文档的展示 URL , 文档内容组成, 倒排索引是一个哈希表的结构, key 是查询词, value 是一个顺序表的结构, 这个顺序表的每个元素都是一个权重类的对象, 这个权重类包含两个属性, 即 文档 id + 文档权重, 权重表示的是文档与查询词的相关性, 后面展示给用户的时候就以权重降序展示, 让用户更可能看到自己想要的搜索结果.

    正排索引和倒排索引结构如下图
    在这里插入图片描述

    正排索引和倒排索引功能介绍
    倒排索引: 里面存储着各种查询词, 只要是文档出现了的词, 就会被加入到倒排索引中, 后续根据用户输入的查询词来倒排索引中查询到文档 id, 再根据 id 去正排索引中查询, 找到查询词对应的文档列表.

    正排索引: 组织 API 文档, 每个文档由 文档 id, 文档标题, 文档的展示 URL , 文档内容组成, 后续通过倒排索引查询到了对应文档的 id , 就通过这个 id 来正排索引中查询到对应 id 的文档, 最后经过包装以展示给用户.

    建立正排索引和倒排索引

    建立正排索引
    获取文档标题: 下载 API 文档到本地, 然后遍历所有的 html 文件(不需要关注别的文件), 直接用文件的 getName() 方法得到文档标题.
    获取文档展示 URL : 注意得到展示 URL, 由于本地的 API 文档路径和 Oracle 在线的 API 文档的 Web 路径的后大半部分是一致的, 所以只要将本地的后部分路径和 Oracle 文档的 Web 路径前部分路径拼接起来, 就可以得到每个文档的展示 URL 了.
    获取文档内容: 关于 API 文档的内容, 直接读取每个文件, 去除标签和部分标签中的内容, 再遍历字符得到正文.

    建立倒排索引
    约定计算权重的方式: 首先就要想好计算权重的方式, 以一个 int 类型的数值来评判权重大小, 这里直接遍历标题和正文, 标题出现了的查询词权重 + 10, 正文出现的查询词权重 + 1.
    对文档标题和正文进行分词: 遍历已经建立好的正排索引, 拿到每个文档, 通过 Ansj 分别对每个文档的标题和正文进行分词, 每个分词就是一个查询词, 以两个列表分别接收标题的分词和正文的分词.
    统计每个分词出现的次数: 先建立一个 hashMap, 用来统计词出现的次数, value 是分词, key是一个对象, 有两个属性, 标题出现次数 + 正文出现次数, 然后先遍历标题的分词, 计算每个词出现的次数, 再遍历正文的分词, 计算每个分词出现的次数, 后续通过这个 hashMap 来计算权重和插入所有的分词到倒排索引中.
    计算权重并添加查询词到倒排索引中: 遍历这个 hashMap, 计算每个查询词在该文档中的权重, 注意这个权重计算方式, 标题出现次数 * 10 + 正文出现次数. 再查看这个查询词是否在倒排索引中, 不存在则添加查询词和查询词对应的权重列表, 并添加这个权重对象到权重列表中, 存在则直接添加权重对象到查询词对应的权重列表中.

  • 搜索模块

    对查询词进行分词: 用户输入查询词, 然后对用户输入的查询词进行分词, 用一个列表接收分词结果.
    去掉分词中的停用词: 遍历这个分词列表, 对这个列表进行停用词去重, 把一些不相干的词去掉, 例如 a, an, hava …
    倒排索引查询分词并汇总权重列表: 遍历分词列表, 去倒排索引中查询每个分词, 记录每一个分词返回的权重列表, 并进行汇总.
    合并权重: 遍历汇总后的权重列表, 进行合并权重, 因为存在输入多个查询词, 搜索到了相同结果的情况, 例如输入 array list , 就会搜索出两个 arraylist 文档. 合并权重, 首先进行文档 id 的升序排序, 这里建立一个堆, 优先级为文档 id, 建立一个返回的权重列表, 存在 id 相同的文档, 则权重相加, 进行合并, 最后返回这个合并后的权重列表.
    文档排序: 对列表进行权重排序, 把权重最高的文档排在最前面.
    文档包装和查询词逻辑标红: 遍历权重列表, 根据 文档 id 去正排索引里查询对应的文档, 准备返回给用户, 每个结果由 文档标题 + 文档描述 + 文档展示 URL 组成, 标题和展示 URL 在正排索引中存在, 这里只要得到描述即可, 直接遍历权重列表, 这里采取的策略是去正文中查找首个存在的查询词, 在这个查询词前后获取部分字符组成描述, 然后再遍历描述中存在的所有查询词, 进行逻辑标红, 即对每个查询词左右添加标签, 后续前端再对这些标签进行渲染.
    返回结果: 用一个对象接收这些结果, 再将返这些结果以 Json 的格式返回给前端.

  • 前端模块
    输入查询词: 用户输入查询词, 点击搜索按钮即发送查询词给服务器.
    接收查询结果: 发送给服务器后, 服务器进行查询, 返回结果给前端.
    判断查询状态: 前端解析后端传来的 Json 格式的结果, 根据返回结果的状态码进行相应的处理, 这里约定 -1 表示不存在该查询词或者表示出现了意料外的异常, 1 表示查询成功.
    展示结果: 前端根据状态码来进行不同的操作, -1 直接 alert, 不存在该查询词或服务器处理异常, 请稍后再试. 这个取决于 -1 对应的message 描述, 1 进行展示搜索结果, 遍历后端返回的结果列表, 拿到每个结果的 文档标题, 文档描述, 文档展示 URL , 创建展示 div, 展示所有的结果.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值