【信息检索】Java简易搜索引擎原理及实现(五)计算查询与文档相似度 + 搜索界面开发 + 服务器快速搭建

本文介绍了如何使用Java构建简易搜索引擎,包括计算查询与文档的相似度,对文档按相似度排序,搜索界面开发以及服务器的快速搭建。查询词预处理涉及对用户输入的分词处理,计算相似度使用特定公式。此外,还实现了相似文档查询功能。最后,通过SpringBoot搭建服务器,并提供了搜索界面的实现思路。
摘要由CSDN通过智能技术生成

在上一篇文章:【信息检索】Java简易搜索引擎原理及实现(四)利用布尔模型和向量模型计算权值,我们已经计算出了最终数据呈现所需使用到的大部分数据,本篇我们将完成最后一步:对查询词进行预处理,并计算出查询词与相关文档的相似度,将文档按相似度由高到低排序。同时,完成搜索界面开发和服务器快速搭建的工作。

1.计算查询与文档相似度

(1)查询词预处理

我们在第三篇文章中,构建出了轮排 加上 B+树的索引结构,本次的查询就是基于该结构开展的,因此我们需要首先获取到构建好的B+树。
在第二篇文章中,其实我们也处理过了 AND 、OR、ANDNOT三种操作符,已经可以由单个词组成的查询链查询出匹配的DocId了。但在实际的查询中,用户可能输入并不是完全按照我们的假设,可能会在一个词的位置输入多个词组。
举个例子来说,例如用户希望查询 【数字图像处理 AND 竞赛】,竞赛就看做一个词,它是可以在我们的词库中查询到的;而数字图像处理这个词,在我们的词库中是找不到这样一个完整的词汇的,因为抓取下来的数据已经在存入B+树之前,就由分词器做过分词了,所以此时B+树中能找到的词只有【数字】、【图像】、【处理】。因此,针对这种情况,我们对每一个输入词进行处理,依然让其通过一次分词器,获取到输入词分词后的结果(DocId),将其与原本的输入词的查询结果(DocId)做并集操作。在这个例子中就是,把【数字图像处理】这个词变为【数字图像处理】OR 【数字】OR【图像】OR【处理】,这样即使造成查询出某些不符合用户原意的结果,也能因为后续还要计算相似度而排名靠后展示。
需要注意的是,由于我们的搜索引擎同时支持精确查询和通配符查询。因此,这种拆分搜索词的操作,我们只对精确查找的内容进行处理,对于含通配符的搜索词,我们是不做这一步的。

下面,我们就进行代码实现:我们假设你已经有了前面实验的代码。

public class Experiment6 {
   
	private static Experiment2 experiment2 = new Experiment2();
	private static Experiment3 experiment3 = new Experiment3();
	public static Map<String, Integer> queryWord_map = new HashMap<>();
	public static Integer queryWord_count = 0;
	
	public static BplusTree bPlusTree;
	
	public static void initBPlusTree() {
   
        bPlusTree = experiment3.exp3(); //轮排 + B+树索引结构
    }
	
	/**
	 * 查询用户搜索内容匹配的DocId
	 * @param input 用户输入
	 * @param bPlusTree B+树和轮排的索引结构
	 * @return 查询出的所有匹配的DocId
	 */
	public static List<Integer> query(String input, BplusTree bPlusTree) {
   
	    String[] in_strs = input.split(" ");
	
	    //单独处理第一个搜索词
	    List<Integer> result = getDocList(experiment3.queryForList(in_strs[0], bPlusTree));
	    List<Integer> next;
	
	    //对输入的一个词进行分词并与原结果合并
	    if (!in_strs[0].contains("*")) {
   
	        result = splitWordMerge(in_strs[0], result); //只对精确查找的词进行此操作
	    }
	
	    int len = in_strs.length;
	    for (int i = 1; i < len; i += 2) {
    //i取奇数
	        next = getDocList(experiment3.queryForList(in_strs[i + 1], bPlusTree));
	        //对输入的一个词进行分词并与原结果合并
	        if (!in_strs[i + 1].contains("*")) {
   
	            next = splitWordMerge(in_strs[i + 1], next); //只对精确查找的词进行此操作
	        }
	
	        //根据操作数合并result和next的DocId
	        switch (in_strs[i]) {
   
	            
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值