😂 😂 😂 没写完,后面(高级)有趣部分没写只把大致的方向写了下 截图图太长,复制代码格式会乱,影响阅读.索性不写以后抽时补上.
🎉 第一次在 这个大家庭发帖 希望有人喜欢我分享的干货,如果对哪里不理解,或者有质疑都可以在下方留言,大家共同探讨,加深印象!
长期更新 分享 Java,Hadoop,Spack,Msyql,Linux 这方面的干货,也希望能找到志同道合的朋友!
并不是不分享代码 <----- > 而是直接上代码 展示效果非常差(所以直接看图吧)!
谢谢~~~
1. 搜索引擎
1.1 什么是搜索引擎
通过爬虫爬取到互联网的信息后,进行组织与处理,为用户提供搜索服务,将检索的相关信息展示给用户!
1.2 搜索引擎基本的运行原理
1.3 原始数据库查询的缺陷
-
- 慢, 当数据库中的数据量很庞大的时候, 整个的查询效率非常低, 无法及时返回内容
-
- 搜索效果比较差, 只能根据用户输入的完整关键字的进行首尾的模糊匹配
-
- 如果用户输入的关键字出现错别字, 或者多输入了内容, 可能就导致结果远离用户期望的内容
1.4 倒排索引技术
倒排索引, 又称为反向索引: 将存储的值进行切分,存入索引库, 每一个关键字都会对应着一个记录项, 记录项中记录了这个关键字出现在哪些文档中, 以及在此文档的什么位置上
为什么说倒排索引可以提升查询的效率和精准度呢?
倒排索引, 是将数据提前按照格式分词放好,建立索引, 当用户进行搜索, 将用户的关键字进行分词, 然后根据分词后的单词到索引库中寻找对应词条,根据词条, 查到对应所在的文档位置, 将其文档内容直接获取即可
2.Lucene
-
Lucene: 底层的 api, 工具包
-
solr: 基于 Lucene 开发的企业级的搜索引擎产品
2.2 使用 Lucene 如何构建索引
2.2.1 第一步: 导入相关的 jar 包(pom 依赖)
长图就不一张一张的截了 直接看 Maven 依赖
2.2.2 第二步: 书写写入索引的代码
2.3 索引查看工具
2.4 API 详解
-
IndexWriter: 索引写入器对象
其主要的作用, 添加索引, 修改索引和删除索引
- 创建此对象的时候, 需要传入 Directory 和 indexWriterConfig 对象
-
Directory: 目录类, 用来指定索引库的目录
-
常用的实现类:
-
FSDirectory: 用来指定文件系统的目录, 将索引信息保存到磁盘上
-
优点: 索引可以进行长期保存, 安全系数高
-
缺点: 读取略慢
-
-
RAMDriectory: 内存目录, 将索引库信息存放到内存中
-
优点: 读取速度快
-
缺点: 不安全, 无法长期保存, 关机后就消失了
-
-
-
-
IndexWriterConfig: 索引写入器的配置类
-
创建此对象, 需要传递 Lucene 的版本和分词器
-
作用:
-
作用 1 : 指定 Lucene 的版本和需要使用的分词器
-
作用 2: 设置 Lucene 的打开索引库的方式: setOpenMode();
-
-
-
Document: 文档
在 Lucene 中, 每一条数据以文档的形式进行存储, 文档中也有其对应的属性和值, Lucene 中一个文档类似数据库的一个表, 表中的字段类似于文档中的字段,只不过这个文档只能保存一条数据
Document 看做是一个文件, 文件的属性就是文档的属性, 文件对应属性的值就是文档的属性的值 content
-
一个文档中可以有多个字段, 每一个字段就是一个 field 对象,不同的文档可以有不同的属性
-
字段也有其对应数据类型, 故 Field 类也提供了各种数据类型的实现类
名称解释:
分析: 是否将字段的值进行分词
索引: 指的是能否被搜索
是否保存: 指的的初始值是否需要保存
如果一个字段中的值可以被分词, 那么必然是支持搜索的
-
Analyzer: 分词器:
用于对文档中的数据进行分词, 其分词的效果取决于分词器的选择, Lucene 中根据各个国家制定了各种语言的分词器,对中文有一个 ChineseAnalyzer 但是其分词的效果, 是将中文进行一个一个字的分开
针对中文分词一般只能使用第三方的分词词:
一般采用 IK 分词器
http://code.google.com/p/ik-analyzer/
2.5 集成 IK 分词器
基本使用:
- 导入相关依赖, 将分词器切换成 ikanalyzer 即可
Code:IndexWriterConfig config = new IndexWriterConfig(Version.LATEST,new IKAnalyzer());
-
高级使用:
ik 分词器在 2012 年更新后, 就在没有更新, 其原因就取决于其强大的扩展功能,以保证 ik 能够持续使用
-
ik 支持对自定义词库, 其可以定义两个扩展的词典
-
- 扩展词典(新创建词功能):有些词 IK 分词器不识别 例如:“蔡徐坤”😄 ,“碉堡了”
-
- 停用词典(停用某些词功能)有些词不需要建立索引 例如:“哦”,“啊”,“的”
-
-
-
如何使用:
将此三个文件复制到项目中
2.6 查询索引
2.6.1 查询入门:
@Test public void indexSearch() throws Exception {
//1. 创建查询的核心对象
FSDirectory d = FSDirectory.open(new File("H:\\test"));
IndexReader reader = DirectoryReader.open(d);
IndexSearcher indexSearcher = new IndexSearcher(reader);
//2. 执行查询
QueryParser queryParser = new QueryParser("content", new IKAnalyzer());
Query query = queryParser.parse("碉堡了");
TopDocs topDocs = indexSearcher.search(query, 10);
//3. 获取文档id
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
//获取得分文档集合
for (ScoreDoc scoreDoc : scoreDocs) {
int id = scoreDoc.doc; //获取文档id
float score = scoreDoc.score;// 返回此文档的得分
Document doc = indexSearcher.doc(id);
String docId = doc.get("id");
String content = doc.get("content");
System.out.println(docId+" "+content+" "+"得分为:"+score);
}
}
}
2.7 查询相关 API 详解
-
IndexSearcher: Lucene 中查询对象, 用来执行查询和排序操作
-
常用方法:
-
search(Query query, int n);//执行查询
-
参数 1: 查询条件
-
参数 2: 返回的最大条数
-
-
search(Query query, int n,Sort sort);
-
参数 1: 查询的条件
-
参数 2: 返回的最大的条数
-
参数 3: 排序
-
-
doc(int id);//根据文档 id 查询文档对象
-
-
-
IndexReader: 索引库读取工具
- 使用 DirectoryReader 来打开索引库
-
Query:查询对象
-
获取方式:
-
通过查询解析器
-
单字段的解析器: queryParse
-
多字段的解析器: multiFieldQueryParse
-
-
使用 Lucene 自定义的实现类
- Lucene 中提供了五种常用的多样化的查询
-
-
-
TopDocs:查询结果对象
-
第一部分: 查询到的总条数
- int topDocs.totalHits
-
第二部分: 得分文档的数组
- ScoreDoc[] topDocs.scoreDocs;
-
-
ScoreDoc: 得分文档对象
-
第一部分: 文档的 id
- topDoc.doc
-
第二部分: 文档的得分
- topDoc.score
-
2.8 多样化查询(特殊查询)
提取一个查询的方法, 传递不同的 query, 即可
//提取一个查询的方法
public void query(Query query) throws Exception{
//1. 创建 查询的核心对象
IndexReader reader = DirectoryReader.open(FSDirectory.open(new File("H:\\test")));
IndexSearcher indexSearcher = new IndexSearcher(reader);
//3. 执行查询
TopDocs topDocs = indexSearcher.search(query, 10);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;//获取得分文档的集合
for (ScoreDoc scoreDoc : scoreDocs) {
//获取文档id
int docId = scoreDoc.doc;
//获取文档得分
float score = scoreDoc.score;
//根据id获取文档
Document doc = indexSearcher.doc(docId);
String content = doc.get("content");
String title = doc.get("title");
System.out.println("文档得分为"+score+content+" "+title);
}}
2.8.1 词条查询: TermQuery
2.8.2 通配符查询: WildcardQuery
2.8.3 模糊查询: FuzzyQuery
2.8.4 数值范围查询: NumericRangeQuery
2.8.5 组合查询: BooleanQuery
2.8 Lucene 的索引修改
2.9 Lucene 的索引删除
3. Lucene 的有趣部分()
3.1 Lucene 的高亮显示
- 高亮: 实际上高亮其实就给对应的字段添加一个 HTML 标签,并设置其 css 样式即可
3.1.1 Lucene 的高亮
3.2 Lucene 的排序
3.3 Lucene 的分页
3.4 Lucene 的加权因子(激励因子)
-
Lucene 会对搜索的结果的匹配度进行一个加分, 用来表示数据和词条关联性的强弱, 得分越高, 表示匹配度越高, 排名越靠前
-
Lucene 支持对某一个字段设置加权因子, 来提高其打分, 使其排名更加靠前, 这样当用户搜索的时候, 便可以将此词条对应的文档展示在最前面
/大白话就不说了 大家应该都知道这个激励因子咋回事/
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于