ElasticSearch搜索引擎的入门实战
1.ElasticSearch简介
引用自百度百科:
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
我们建立一个网站或应用程序,并要添加搜索功能,但是想要完成搜索工作的创建是非常困难的。我们希望搜索解决方案要运行速度快,我们希望能有一个零配置和一个完全免费的搜索模式,我们希望能够简单地使用JSON通过HTTP来索引数据,我们希望我们的搜索服务器始终可用,我们希望能够从一台开始并扩展到数百台,我们要实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案。因此我们利用Elasticsearch来解决所有这些问题及可能出现的更多其它问题。
2.ElasticSearch的安装
2.1.安装Jdk1.8
1 |
|
2.2.安装elasticsearch-2.4.1
1、下载
1 |
|
2、解压 注意解压路径不能为root
1 |
|
3、配置 找到解压后的config文件夹打开elasticsearch.yml
关键是要打开network.host: 0.0.0.0和http.port: 9200注释,提供web访问
1 |
|
4、设置文件可访问权限
1 |
|
5、注意这里不能直接启动 用root用户启动会报错 所以我们需要新建一个用户
1 |
|
6、启动 在bin目录下执行命令(最后可加& 表示在后台运行)
1 |
|
7、查看内存
执行命令
1 |
|
8、查看内存 优化内存
可以看到在内存为2G的主机上,Elasticsearch的运行内存为 -Xms256m -Xmx1g
1.最简单的一个方法就是指定ES_HEAP_SIZE环境变量。服务进程在启动时候会读取这个变量,并相应的设置堆的大小。设置命令如下:
1 |
|
9、访问网页
因为开启了http访问,并设置可以远程连接,所以我们直接请求网址即可:
1 |
|
相应内容如下:
1 |
|
10、可视化插件
利用在bin目录下提供的plugin插件安装head,实现web可视化
注意目录:
1 |
|
安装完后访问
1 |
|
3.使用logstash导入mysql数据到elasticSearch
Elasticsearch-jdbc工具包(废弃),虽然是官方推荐的,但是已经几年不更新了。所以选择安装logstash-input-jdbc,首选 logstash-input-jdbc,logstash5.X开始,已经至少集成了logstash-input-jdbc插件。所以,你如果使用的是logstash5.X,可以不必再安装,可以直接跳过这一步。
3.1.下载mysql-jdbc-driver.jar
下载地址:
1 |
|
此处我使用的jar的版本为:mysql-connector-java-5.1.46.jar.后面我们会把这个jar包放在logstash的config目录下面
3.2.下载logstash-6.3.0
下载命令:
1 |
|
解压命令:
1 |
|
3.3.elasticSearch与数据库表的对应关系
ES | MYSQL |
---|---|
索引 | 数据库 |
类型 | 数据表 |
文档 | 数据表的一行 |
属性 | 数据表的一列 |
3.4.建立测试数据表
sql语句如下:
1 |
|
在logstatsh的目录下面建立my_logstash文件夹,里面建立myjdbc.conf:(这个仅供参考 实际不使用)
1 |
|
在logstash的config目录下面新建logstash-mysql.conf:
1 |
|
启动命令:
1 |
|
启动成功后界面如下,开始导入数据:
访问地址:http://192.168.142.131:9200/_plugin/head/
4.查询语句相关
URL查询:
1 |
|
响应:
1 |
|
相关参数
如下这些参数可以使用统一资源标识符在搜索操作中传递 -
编号 | 参数 | 说明 |
---|---|---|
1 | Q | 此参数用于指定查询字符串。 |
2 | lenient | 基于格式的错误可以通过将此参数设置为true 来忽略。默认情况下为false 。 |
3 | fields | 此参数用于在响应中选择返回字段。 |
4 | sort | 可以通过使用这个参数获得排序结果,这个参数的可能值是fieldName ,fieldName:asc 和fieldname:desc |
5 | timeout | 使用此参数限定搜索时间,响应只包含指定时间内的匹配。默认情况下,无超时。 |
6 | terminate_after | 可以将响应限制为每个分片的指定数量的文档,当到达这个数量以后,查询将提前终止。 默认情况下不设置terminate_after 。 |
7 | 从命中的索引开始返回。默认值为0 。 |
|
8 | size | 它表示要返回的命中数。默认值为10 。 |
5.短语搜索
5.1.短语搜索是ElasticSearch中比较常用的方式,相关的语法个格式为JSON,如下:(这里使用POSTMAN进行演示)
1 |
|
请求体:
1 |
|
响应:
1 |
|
5.2.提高精度搜索:
搜索结果精准控制的第一步:灵活使用and关键字,如果你是希望所有的搜索关键字都要匹配的,那么就用and,可以实现单纯match query无法实现的效果
1 |
|
控制搜索结果的精准度的第二步:指定一些关键字中,必须至少匹配其中的多少个关键字,才能作为结果返回
1 |
|
用bool组合多个搜索条件,来搜索name
1 |
|
-
注意:bool组合多个搜索条件,如何计算relevance score
must和should搜索对应的分数,加起来,除以must和should的总数
排名第一:test,同时包含should中所有的关键字,testOne,testTwo 排名第二:test,同时包含should中的testOne 排名第三:test,不包含should中的任何关键字
should是可以影响相关度分数的,must是确保说,谁必须有这个关键字,同时会根据这个must的条件去计算出document对这个搜索条件的relevance score,在满足must的基础之上,should中的条件,不匹配也可以,但是如果匹配的更多,那么document的relevance score就会更高
-
默认情况下,should是可以不匹配任何一个的,比如上面的搜索中,”李四”,就不匹配任何一个should条件,但是有个例外的情况,如果没有must的话,那么should中必须至少匹配一个才可以,比如下面的搜索,should中有4个条件,默认情况下,只要满足其中一个条件,就可以匹配作为结果返回,但是可以精准控制,should的4个条件中,至少匹配几个才能作为结果返回
1 |
|
-
指定返回属性
只返回查询文档的name和age属性
1 |
|
- 高亮搜索
1 |
|
返回如下:
1 |
|
6.使用SpringBoot+ElasticSearch
这里我们需要注意SpringBoot和ElasticSearch的版本号能对应,我们查看官网的介绍进行构建项目:
https://github.com/spring-projects/spring-data-elasticsearch ,主要点如下所示:
Maven configuration
Add the Maven dependency:
1 |
|
If you’d rather like the latest snapshots of the upcoming major version, use our Maven snapshot repository and declare the appropriate dependency version.
1 |
|
Versions
The following table shows the Elasticsearch versions that are used by Spring Data Elasticsearch:
Spring Data Elasticsearch | Elasticsearch |
---|---|
3.2.x | 6.7.2 |
3.1.x | 6.2.2 |
3.0.x | 5.5.0 |
2.1.x | 2.4.0 |
2.0.x | 2.2.0 |
1.3.x | 1.5.2 |
我们这里的elastic的版本为2.4.1,所以我们选取2.4.1.RELEASE:
1 |
|
然后在application.yml配置一下服务器的elasticsearch地址(注意线上的建立连接监听的端口为9300,并非9200):
1 |
|
配置好后启动我们的项目,会打印如下的日志,说明连接成功:
完整pom文件如下:
1 |
|
入门Demo:
ElasticsearchCRUD介绍网站:https://damienbod.com/2014/10/01/full-text-search-with-asp-net-mvc-jquery-autocomplete-and-elasticsearch/
The article explains how to use the ElasticsearchCRUD NuGet package. ElasticsearchCRUD is designed so that you can do CRUD operations for any entity and insert, delete, update or select single documents from Elasticsearch. The package only includes basic search or query possibilities. (本文解释了如何使用ElasticsearchCRUD NuGet包。ElasticsearchCRUD的设计使您可以对任何实体执行CRUD操作,并从Elasticsearch中插入、删除、更新或选择单个文档。该包只包含基本的搜索或查询可能性。 )
6.1.1.我们先基于student表创建一个实体类用于测试
1 |
|
6.1.2.新建新建ElasticsearchRepository接口
1 |
|
6.1.3.测试
1 |
|
StudentRepository可以使用如下关键字来实现复杂的操作:
关键字 | 使用示例 | 等同于的ES查询 |
---|---|---|
And | findByNameAndPrice | {“bool” : {“must” : [ {“field” : {“name” : “?”}}, {“field” : {“price” : “?”}} ]}} |
Or | findByNameOrPrice | {“bool” : {“should” : [ {“field” : {“name” : “?”}}, {“field” : {“price” : “?”}} ]}} |
Is | findByName | {“bool” : {“must” : {“field” : {“name” : “?”}}}} |
Not | findByNameNot | {“bool” : {“must_not” : {“field” : {“name” : “?”}}}} |
Between | findByPriceBetween | {“bool” : {“must” : {“range” : {“price” : {“from” : ?,”to” : ?,”include_lower” : true,”include_upper” : true}}}}} |
LessThanEqual | findByPriceLessThan | {“bool” : {“must” : {“range” : {“price” : {“from” : null,”to” : ?,”include_lower” : true,”include_upper” : true}}}}} |
GreaterThanEqual | findByPriceGreaterThan | {“bool” : {“must” : {“range” : {“price” : {“from” : ?,”to” : null,”include_lower” : true,”include_upper” : true}}}}} |
Before | findByPriceBefore | {“bool” : {“must” : {“range” : {“price” : {“from” : null,”to” : ?,”include_lower” : true,”include_upper” : true}}}}} |
After | findByPriceAfter | {“bool” : {“must” : {“range” : {“price” : {“from” : ?,”to” : null,”include_lower” : true,”include_upper” : true}}}}} |
Like | findByNameLike | {“bool” : {“must” : {“field” : {“name” : {“query” : “? *”,”analyze_wildcard” : true}}}}} |
StartingWith | findByNameStartingWith | {“bool” : {“must” : {“field” : {“name” : {“query” : “? *”,”analyze_wildcard” : true}}}}} |
EndingWith | findByNameEndingWith | {“bool” : {“must” : {“field” : {“name” : {“query” : “*?”,”analyze_wildcard” : true}}}}} |
Contains/Containing | findByNameContaining | {“bool” : {“must” : {“field” : {“name” : {“query” : “?”,”analyze_wildcard” : true}}}}} |
In | findByNameIn(Collectionnames) | {“bool” : {“must” : {“bool” : {“should” : [ {“field” : {“name” : “?”}}, {“field” : {“name” : “?”}} ]}}}} |
NotIn | findByNameNotIn(Collectionnames) | {“bool” : {“must_not” : {“bool” : {“should” : {“field” : {“name” : “?”}}}}}} |
True | findByAvailableTrue | {“bool” : {“must” : {“field” : {“available” : true}}}} |
False | findByAvailableFalse | {“bool” : {“must” : {“field” : {“available” : false}}}} |
OrderBy | findByAvailableTrueOrderByNameDesc | {“sort” : [{ “name” : {“order” : “desc”} }],”bool” : {“must” : {“field” : {“available” : true}}}} |