搜索引擎基础及核心思想

前言

本篇文章会通过介绍搜索引擎的基础及在项目中为什么会出现搜索引擎,以及搜索引擎如何实现,包括提到创建索引,对于半结构化数据以及结构化数据快速找到我们想要的数据,以及在大数据条件下Lucene  es架构的一个介绍。

搜索引擎

为什么需要搜索引擎

我们在工作中存储数据是通过oracle mysql等关系型数据库进行存储

如果按上图中按不同的类别或者 时间  查询某个标题 分别进行查询。在数据库中按照不同的sql语句进行查找

 对于数据库中数据量增大查询效率降低,这些个sql就需要进行优化了,最开始想到的办法 建索引、分区表。

而创建的索引的原理
对列值创建排序存储,数据结构={列值、行地址}。在有序数据列表中就可以利用
二分查找快速找到要查找的行的地址,再根据地址直接取行数据。

在增加数据时对数据进行全量的的先进行排序。 并且创建 对应的数据结构。  这就是一个索引的原理,怎么快速查找到数据

 索引排序  一般是按照数值 和时间

  • 数值列
  • 时间列
  • 文本列      一般也不建议使用文本列,但如果必须需要,则使用按字符集的编码值进行排序。

在“新闻标题”列上建索引后,当我们查询 标题 = ‘钓鱼岛’

直接使用=号就可以快速 查找到数据,  直接对比

如果当 存在这种情况 而当我们查询 标题 LIKE ‘%钓鱼岛%’ 的情况 ,这种情况 索引是无法识别的。  效率会降低。 对于 左边有的时候,可以查找到

如果数据量特别大,对于索引来说都是不够用的,而且 添加 数据时效率会变慢,这对于访问效率来说也是不利的。

数据库适合结构化数据的精确查询,而不适合半结构化、非结构化数据的模糊
查询及灵活搜索(特别是数据量大时),无法提供想要的实时性。
  • 结构化数据: 用表、字段表示的数据
  •  半结构化数据: xml html
  • 非结构化数据: 文本、文档、图片、音频、视频等

这里引入了 搜索引擎的概念  。

概述

搜索引擎,就是根据用户需求与一定算法,运用特定策略从数据库中检索出制定信息反馈给用户的一门检索技术。

其中会涉及到使用分词器对数据进行分词,建立反向索引,进行搜索。

 搜索的步骤

  • 对搜索输入进行分词
  • 在反向索引中找出包含 钓鱼岛、中国 的文章列表
  •  合并两个列表,排序输出

倒排索引

在存储时, 将索引结构,按照关键词进行建立起来索引  

我们查询时,输入的是“钓鱼岛是中国的”,想要得到标题或内容中包含“钓鱼岛是中国的”的新闻列表。

 这就能创建索引,快速 找到  标题中包含某个词的,以及  内容 中包含文章的id.

这里是可以合并的。

倒排索引:英文原名Inverted index,失败地翻译成了倒排索引,正确翻译为: 反向索引
词→文章

 可以某个词,快速查找到文章

反向索引的记录数 的记录都是词的多少 ,其实并不多
量不会很大, 100 万以内;通过这个索引找文章会很快。   
数据量并不大 ,因此 一般反向索引,还是不多的。

正向索引

文章→词 

和反向索引正好相反,利用  文章id 进行分组,  在查找时,能快速查找  某篇文章 找到关键词

分词器

  何建立这样一个索引,分词器 这个的效果,将词进行提取。 我们想到最简单的方式就是jdk中提供的 利用什么 string.split 方法都可以达到。
而且对于不同的语言应该有不同的分词器。
必须写一套专门的程序来做这个事情 :分词器
每门语言有对应的分词器
而中文则采用下面的方式:
有个词的字典,对语句前后字进行组合,与字典匹配,歧义分析
语句示例
张三说的确实在理。
人是怎么对这句话分词 ,从头开始一个一个字读,通过 前后字的组合 ,分出:张三、说的、确实、在理。
我们从小学语文时,就是按照词性和 语义进行分类,这就是给我们大脑进行装词组,而读到这句话时,能立马进行分词,分句,学英文这些都是一样。 而分词器 也是需要达到这种效果。
也需要设置预先词组。
java开源中文分词器
 总的来说 选择方式
1、准确率 2、分词效率 3、中英文混合分词支持
常用中文分词器有: IKAnalyzer mmseg4j

一般分词器在分词时统计 词出现的次数 位置,也是 快速 查找到数据

 这种的应用场景可以在百度中,可以进行高亮等操作

而且对于分词器来说 ,你、我、他、的、地、了、标点符号…..这些并不需要为其创建索引,统一称之停用词。

当出现了新词了,需要提供方法加到词典中去。

输出

对于搜索引擎来说,如何度量 相关性的,

人可以通过读内容判定相关性,机器不懂人话。 得建立一套能评估相关性的模型。
  • 规则1: 统计出现次数,根据次数从高到低排序

{{1,5},{5,3},{12,1},{8,1}}  

  •  规则2: 加入权重,标题权重10,内容权重1,计算权重得分,按高-低排序
{{1,23},{12,10},{5,3},{8,1}}

通过自己的设置的。

复杂的相关性计算模型有:
  • tf-idf 词频-逆文档率模型
  •  向量空间模型
  •  贝叶斯概率模型,如: BM25
搜索引擎中会提供一种、或多种实现供选择使用,也会提供扩展。
电商网站中的搜索相关性计算会考虑更多,更复杂。
以及反向索引更新:数据更新时,索引是不是必须得更新。都需要维护原来得索引进行维护。
对于所有得搜索引擎,对索引操作,都是先删除原来得操作,在新增,不存在真正得更新。
反向索引,不一定是在磁盘 也不一定是在内存中。
并且对于搜索引擎来说  支持像数据库一样的多条件AND OR 组合搜索。
所有得搜索引擎都是遵从上面得原理。

Lucene

最受欢迎的java开源全文搜索引擎开发工具包。提供了完整的查询引擎和索引引擎,部分文本分词引擎。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便在目标系统中实现全文检索功能,或者是以此为基础建立起完整的全文检索引擎。

可以通过这样得方式进行检索。

 <dependency>
          <groupId>org.elasticsearch.client</groupId>
          <artifactId>transport</artifactId>
          <version>6.4.0</version>
      </dependency>

 可以使用Lucene开发一个搜索引擎,首先,准备目录 准备分词器 准备config 创建索引的实例

 //创建索引
    public static void createIndex(String indexDir){
        IndexWriter writer = null;
        try {
            //准备目录
            Directory directory = FSDirectory.open(Paths.get((indexDir)));
            //准备分词器
            Analyzer analyzer = new StandardAnalyzer();
            //准备config
            IndexWriterConfig iwConfig = new IndexWriterConfig(analyzer);
            //创建索引的实例
            writer = new IndexWriter(directory, iwConfig);

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (writer != null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

把文档进行索引进去 创建索引,属于进行Lucene 进行

//索引文档
    public static void indexDoc(String indexDir, String jsonDoc){
        IndexWriter writer = null;
        try {
            //准备目录
            Directory directory = FSDirectory.open(Paths.get((indexDir)));
            //准备分词器
            Analyzer analyzer = new StandardAnalyzer();
            //准备config
            IndexWriterConfig iwConfig = new IndexWriterConfig(analyzer);
            //创建索引的实例
            writer = new IndexWriter(directory, iwConfig);

            Document doc = json2Doc(jsonDoc);
            writer.addDocument(doc);

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (writer != null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 最后查询数据  

  • 准备目录
  • 拿到reader
  • 创建indexSearcher实例
  • 准备分词器
  • 创建解析器
  • 拿到文档实例
  • 拿到所有文档字段
  • 处理文档字段

es就是对Lucene进行封装得搜索引擎

分片和副本

shard、replica

shard
一个index可能存储大量的数据,以至于一台机器存放不下,即使能承载,由
单台机器查询全量数据,也相当耗时。为了解决这个问题,ES将index中数据分为
多份,每份叫一个shard。

ES采用得方式 就是采用分片  进行拆分开,独立起来。提高分布式执行得效率。

replica
    replica即为shard的备份,每个shard可以有多个replica,其中一个位
primary shard,剩余的为replica shard。Replica除可以起到容错的作用外,还
可以提高查询并发度。

ES将index的数据分为多份,每份叫一个shard,为了提高数据可用性,每个shard都
会有冗余副本,每个副本实际上是一个Lucene index实例.
ES架构

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踩踩踩从踩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值