搜索引擎基础及核心思想
Posted 踩踩踩从踩
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搜索引擎基础及核心思想相关的知识,希望对你有一定的参考价值。
前言
本篇文章会通过介绍搜索引擎的基础及在项目中为什么会出现搜索引擎,以及搜索引擎如何实现,包括提到创建索引,对于半结构化数据以及结构化数据快速找到我们想要的数据,以及在大数据条件下Lucene es架构的一个介绍。
搜索引擎
为什么需要搜索引擎
我们在工作中存储数据是通过oracle mysql等关系型数据库进行存储
如果按上图中按不同的类别或者 时间 查询某个标题 分别进行查询。在数据库中按照不同的sql语句进行查找
对于数据库中数据量增大查询效率降低,这些个sql就需要进行优化了,最开始想到的办法 建索引、分区表。
对列值创建排序存储,数据结构={列值、行地址}。在有序数据列表中就可以利用二分查找快速找到要查找的行的地址,再根据地址直接取行数据。
在增加数据时对数据进行全量的的先进行排序。 并且创建 对应的数据结构。 这就是一个索引的原理,怎么快速查找到数据
索引排序 一般是按照数值 和时间
- 数值列
- 时间列
- 文本列 一般也不建议使用文本列,但如果必须需要,则使用按字符集的编码值进行排序。
在“新闻标题”列上建索引后,当我们查询 标题 = ‘钓鱼岛’
直接使用=号就可以快速 查找到数据, 直接对比
如果当 存在这种情况 而当我们查询 标题 LIKE ‘%钓鱼岛%’ 的情况 ,这种情况 索引是无法识别的。 效率会降低。 对于 左边有的时候,可以查找到
如果数据量特别大,对于索引来说都是不够用的,而且 添加 数据时效率会变慢,这对于访问效率来说也是不利的。
数据库适合结构化数据的精确查询,而不适合半结构化、非结构化数据的模糊查询及灵活搜索(特别是数据量大时),无法提供想要的实时性。
- 结构化数据: 用表、字段表示的数据
- 半结构化数据: xml html
- 非结构化数据: 文本、文档、图片、音频、视频等
这里引入了 搜索引擎的概念 。
概述
搜索引擎,就是根据用户需求与一定算法,运用特定策略从数据库中检索出制定信息反馈给用户的一门检索技术。
其中会涉及到使用分词器对数据进行分词,建立反向索引,进行搜索。
搜索的步骤
- 对搜索输入进行分词
-
在反向索引中找出包含 钓鱼岛、中国 的文章列表
- 合并两个列表,排序输出
倒排索引
在存储时, 将索引结构,按照关键词进行建立起来索引
这就能创建索引,快速 找到 标题中包含某个词的,以及 内容 中包含文章的id.
这里是可以合并的。
可以某个词,快速查找到文章
量不会很大, 100 万以内;通过这个索引找文章会很快。
正向索引
文章→词
分词器
一般分词器在分词时统计 词出现的次数 位置,也是 快速 查找到数据
这种的应用场景可以在百度中,可以进行高亮等操作
而且对于分词器来说 ,你、我、他、的、地、了、标点符号…..这些并不需要为其创建索引,统一称之停用词。
输出
对于搜索引擎来说,如何度量 相关性的,
- 规则1: 统计出现次数,根据次数从高到低排序
{{1,5},{5,3},{12,1},{8,1}}
- 规则2: 加入权重,标题权重10,内容权重1,计算权重得分,按高-低排序
{{1,23},{12,10},{5,3},{8,1}}
通过自己的设置的。
- tf-idf 词频-逆文档率模型
- 向量空间模型
- 贝叶斯概率模型,如: BM25
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
ES采用得方式 就是采用分片 进行拆分开,独立起来。提高分布式执行得效率。
以上是关于搜索引擎基础及核心思想的主要内容,如果未能解决你的问题,请参考以下文章