目录
一、目标
二、ElasticSearch介绍
1、简介
总结
突出优点
es、Lucene、solr对比
2、Elasticsearch基本概念:
倒排索引:倒排索引操作步骤:
三、RESTful应用方法
四、ElasticaSearch安装
安装配置:
2、配置文件2.1 三个配置文件
2.2 elasticsearch.yml
2.3 jvm.options
2.4 log4j2.properties
2.5 系统配置
2.3 启动ES
2.4 head插件安装
五、ES快速入门
5.1 创建索引库
5.2 创建映射
5.3 创建文档
5.4 搜索文档
5.4.1查询结果分析
六、 IK分词器
6.1测试分词器
6.2 安装IK分词器
6.3 两种分词模式
6.4 自定义词库
搜索ElasticsearchTemplate
搜索方法查询全部 matchAllQuery
布尔查询 boolQuery
精确匹配 termQuery
短语匹配 matchPhraseQuery
无评分查询 constantScoreQuery
普通查询 matchQuery
范围查询 range
索引Bboss
索引库
增删改查
一、目标
Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用Elasticsearch的水平伸缩性,能使数据在生产环境变得更有价值。Elasticsearch 的实现原理主要分为以下几个步骤,首先用户将数据提交到Elasticsearch 数据库中,再通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据,当用户搜索数据时候,再根据权重将结果排名,打分,再将返回结果呈现给用户。
Elasticsearch是与名为Logstash的数据收集和日志解析引擎以及名为Kibana的分析和可视化平台一起开发的。这三个产品被设计成一个集成解决方案,称为“Elastic Stack”(以前称为“ELK stack”)。
Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。Elasticsearch是分布式的,这意味着索引可以被分成分片,每个分片可以有0个或多个副本。每个节点托管一个或多个分片,并充当协调器将操作委托给正确的分片。再平衡和路由是自动完成的。相关数据通常存储在同一个索引中,该索引由一个或多个主分片和零个或多个复制分片组成。一旦创建了索引,就不能更改主分片的数量。
Elasticsearch使用Lucene,并试图通过JSON和Java API提供其所有特性。它支持facetting和percolating,如果新文档与注册查询匹配,这对于通知非常有用。另一个特性称为“网关”,处理索引的长期持久性;例如,在服务器崩溃的情况下,可以从网关恢复索引。Elasticsearch支持实时GET请求,适合作为NoSQL数据存储,但缺少分布式事务。 [1]
官方网址:Elasticsearch:官方分布式搜索和分析引擎 | Elastic
Github:https://github.com/elastic/elasticsearch
ES中有几个基本概念:索引(index)、类型(type)、文档(document)、映射(mapping)等。我们将这几个概念与传统的关系型数据库中的库、表、行、列等概念进行对比,如下表:
这样在用户检索关键字时, 可以先查找关键字索引,在通过关键字与文档的对应关系查找到所在的文档。
现在,如果我们想搜索 quick brown ,我们只需要查找包含每个词条的文档:
两个文档都匹配,但是第一个文档比第二个匹配度更高。如果我们使用仅计算匹配词条数量的简单 相似性算法 , 那么,我们可以说,对于我们查询的相关性来讲,第一个文档比第二个文档更佳。
索引(index):
索引是ES的一个逻辑存储,对应关系型数据库中的库,ES可以把索引数据存放到服务器中,也可以sharding(分片)后存储到多台服务器上。每个索引有一个或多个分片,每个分片可以有多个副本。
类型(type):
ES中,一个索引可以存储多个用于不同用途的对象,可以通过类型来区分索引中的不同对象,对应关系型数据库中表的概念。但是在ES6.0开始,类型的概念被废弃,ES7中将它完全删除。删除type的原因:
我们一直认为ES中的“index”类似于关系型数据库的“database”,而“type”相当于一个数据表。ES的开发者们认为这是一个糟糕的认识。例如:关系型数据库中两个数据表示是独立的,即使他们里面有相同名称的列也不影响使用,但ES中不是这样的。
我们都知道elasticsearch是基于Lucene开发的搜索引擎,而ES中不同type下名称相同的filed最终在Lucene中的处理方式是一样的。举个例子,两个不同type下的两个user_name,在ES同一个索引下其实被认为是同一个filed,你必须在两个不同的type中定义相同的filed映射。否则,不同type中的相同字段名称就会在处理中出现冲突的情况,导致Lucene处理效率下降。
去掉type能够使数据存储在独立的index中,这样即使有相同的字段名称也不会出现冲突,就像ElasticSearch出现的第一句话一样“你知道的,为了搜索····”,去掉type就是为了提高ES处理数据的效率。
除此之外,在同一个索引的不同type下存储字段数不一样的实体会导致存储中出现稀疏数据,影响Lucene压缩文档的能力,导致ES查询效率的降低
文档(document):
存储在ES中的主要实体叫文档,可以理解为关系型数据库中表的一行数据记录。每个文档由多个字段(field)组成。区别于关系型数据库的是,ES是一个非结构化的数据库,每个文档可以有不同的字段,并且有一个唯一标识。
映射(mapping):
mapping是对索引库中的索引字段及其数据类型进行定义,类似于关系型数据库中的表结构。ES默认动态创建索引和索引类型的mapping,这就像是关系型数据中的,无需定义表机构,更不用指定字段的数据类型。当然也可以手动指定mapping类型。
ES集群核心概念:
1、集群(cluster)
一个ES集群由多个节点(node)组成, 每个集群都有一个共同的集群名称最为标识
2、节点(node)
一个es实例即为一个节点,一台机器可以有多个节点,正常使用下每个实例都应该会部署在不同的机器上。ES的配置文件中可以通过node.master、 node.data 来设置节点类型
node节点的组合方式:
3、分片(shard):
如果我们的索引数据量很大,超过硬件存放单个文件的限制,就会影响查询请求的速度,ES引入了分片技术。一个分片本身就是一个完成的搜索引擎,文档存储在分片中,而分片会被分配到集群中的各个节点中,随着集群的扩大和缩小,ES会自动的将分片在节点之间进行迁移,以保证集群能保持一种平衡。分片有以下特点:
4、副本:replica
副本(replica shard)就是shard的冗余备份,它的主要作用:
下图是es在项目中的应用方式:
1、新版本要求至少jdk1.8以上。
2、支持tar、zip、rpm等多种安装方式。
在windows下开发建议使用ZIP安装方式。
3、支持docker方式安装
详细参见:https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html
下载ES: Elasticsearch 版本根据
https://www.elastic.co/downloads/past-releases;版本根据自己需要下载
解压 elasticsearch-6.2.1.zip
bin:脚本目录,包括:启动、停止等可执行脚本
config:配置文件目录
data:索引目录,存放索引文件的地方
logs:日志目录
modules:模块目录,包括了es的功能模块
plugins :插件目录,es支持插件机制
ES的配置文件的地址根据安装形式的不同而不同:
配置文件如下:
配置格式是YAML,可以采用如下两种方式:
方式1:层次方式
path: data: /var/lib/elasticsearch logs: /var/log/elasticsearch
方式2:属性方式
path.data: /var/lib/elasticsearch path.logs: /var/log/elasticsearch
本项目采用方式2,例子如下:
cluster.name: toms
node.name: toms_node_1
network.host: 0.0.0.0
http.port: 9200
transport.tcp.port: 9300
node.master: true
node.data: true
#discovery.zen.ping.unicast.hosts: ["0.0.0.0:9300", "0.0.0.0:9301", "0.0.0.0:9302"]
discovery.zen.minimum_master_nodes: 1
bootstrap.memory_lock: false
node.max_local_storage_nodes: 1
path.data: D:\ElasticSearch\elasticsearch‐6.2.1\data
path.logs: D:\ElasticSearch\elasticsearch‐6.2.1\logs
http.cors.enabled: true
http.cors.allow‐origin: /.*/
注意path.data和path.logs路径配置正确。
常用的配置项如下
cluster.name:配置elasticsearch的集群名称,默认是elasticsearch。建议修改成一个有意义的名称。
node.name:节点名,通常一台物理服务器就是一个节点,es会默认随机指定一个名字,建议指定一个有意义的名称,方便管理一个或多个节点组成一个cluster集群,集群是一个逻辑的概念,节点是物理概念,后边章节会详细介绍。
path.conf: 设置配置文件的存储路径,tar或zip包安装默认在es根目录下的config文件夹,rpm安装默认在/etc/
elasticsearch path.data: 设置索引数据的存储路径,默认是es根目录下的data文件夹,可以设置多个存储路径,用逗号隔开。
path.logs: 设置日志文件的存储路径,默认是es根目录下的logs文件夹 path.plugins: 设置插件的存放路径,默认是es根目录下的plugins文件夹
bootstrap.memory_lock: true 设置为true可以锁住ES使用的内存,避免内存与swap分区交换数据。
network.host: 设置绑定主机的ip地址,设置为0.0.0.0表示绑定任何ip,允许外网访问,生产环境建议设置为具体的ip。
http.port: 9200 设置对外服务的http端口,默认为9200。
transport.tcp.port: 9300 集群结点之间通信端口
node.master: 指定该节点是否有资格被选举成为master结点,默认是true,如果原来的master宕机会重新选举新的master。
node.data: 指定该节点是否存储索引数据,默认为true。
discovery.zen.ping.unicast.hosts: ["host1:port", "host2:port", "..."] 设置集群中master节点的初始列表。
discovery.zen.ping.timeout: 3s 设置ES自动发现节点连接超时的时间,默认为3秒,如果网络延迟高可设置大些。
discovery.zen.minimum_master_nodes:主结点数量的最少值 ,此值的公式为:(master_eligible_nodes / 2) + 1 ,比如:有3个符合要求的主结点,那么这里要设置为2。
node.max_local_storage_nodes:单机允许的最大存储结点数,通常单机启动一个结点建议设置为1,开发环境如果单机启动多个节点可设置大于1.
设置最小及最大的JVM堆内存大小:
在jvm.options中设置 -Xms和-Xmx:
1) 两个值设置为相等
2) 将 Xmx 设置为不超过物理内存的一半。
日志文件设置,ES使用log4j,注意日志级别的配置。
在linux上根据系统资源情况,可将每个进程最多允许打开的文件数设置大些。
su limit -n 查询当前文件数
使用命令设置limit:
先切换到root,设置完成再切回elasticsearch用户。
sudo su
ulimit ‐n 65536
su elasticsearch
也可通过下边的方式修改文件进行持久设置
/etc/security/limits.conf
将下边的行加入此文件:
elasticsearch ‐ nofile 65536
进入bin目录,在cmd下运行:elasticsearch.bat
浏览器输入:http://localhost:9200
显示结果如下(配置不同内容则不同)说明ES启动成功:
{
"name" : "toms_node_1",
"cluster_name" : "toms",
"cluster_uuid" : "J18wPybJREyx1kjOoH8T‐g",
"version" : {
"number" : "6.2.1",
"build_hash" : "7299dc3",
"build_date" : "2021‐12‐07T19:34:26.990113Z",
"build_snapshot" : false,
"lucene_version" : "7.2.1",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
head插件是ES的一个可视化管理插件,用来监视ES的状态,并通过head客户端和ES服务进行交互,比如创建映
射、创建索引等,head的项目地址在https://github.com/mobz/elasticsearch-head。
从ES6.0开始,head插件支持使得node.js运行。
1、安装node.js
2、下载head并运行
git clone git://github.com/mobz/elasticsearch-head.git cd elasticsearch-head npm install npm run start open
HTTP://本地主机:9100 /
3、运行
打开浏览器调试工具发现报错:
Origin null is not allowed by Access-Control-Allow-Origin.
原因是:head插件作为客户端要连接ES服务(localhost:9200),此时存在跨域问题,elasticsearch默认不允许跨域访问。
解决方案:
注意:将config/elasticsearch.yml另存为utf-8编码格式。
成功连接ES
1)使用postman或curl这样的工具创建:
put http://localhost:9200/索引库名称
{
"settings": {
"index": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}
}number_of_shards:设置分片的数量,在集群中通常设置多个分片,表示一个索引库将拆分成多片分别存储不同的结点,提高了ES的处理能力和高可用性,入门程序使用单机环境,这里设置为1。
number_of_replicas:设置副本的数量,设置副本是为了提高ES的高可靠性,单机环境设置为0.
备注:也可以通过head插件新建
我们要把课程信息存储到ES中,这里我们创建课程信息的映射,先来一个简单的映射,如下:
发送:post http://localhost:9200/索引库名称/类型名称/_mapping
创建类型为xc_course的映射,共包括三个字段:name、description、studymondel
由于ES6.0版本还没有将type彻底删除,所以暂时把type起一个没有特殊意义的名字。
post 请求:http://localhost:9200/xc_course/doc/_mapping
表示:在xc_course索引库下的doc类型下创建映射。doc是类型名,可以自定义,在ES6.0中要弱化类型的概念,给它起一个没有具体业务意义的名称。
{
"properties": {
"name": {
"type": "text"
},
"description": {
"type": "text"
},
"studymodel": {
"type": "keyword"
}
}
}
ES中的文档相当于MySQL数据库表中的记录。
发送:put 或Post http://localhost:9200/xc_course/doc/id值 (如果不指定id值ES会自动生成ID) http://localhost:9200/xc_course/doc/4028e58161bcf7f40161bcf8b77c0000
{ "name":"Bootstrap开发框架", "description":"Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包 含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长页面开发的程序人员)轻松的实现一个不受浏览器限制的 精美界面效果。", "studymodel":"201001" }
1、根据课程id查询文档 发送:get http://localhost:9200/xc_course/doc/4028e58161bcf7f40161bcf8b77c0000 使用postman测试:
发送 get http://localhost:9200/xc_course/doc/_search
3、查询名称中包括spring 关键字的的记录 发送:get http://localhost:9200/xc_course/doc/_search?q=name:bootstrap
4、查询学习模式为201001的记录 发送 get http://localhost:9200/xc_course/doc/_search?q=studymodel:201001
分析上边查询结果:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [{
"_index": "xc_course",
"_type": "doc",
"_id": "4028e58161bcf7f40161bcf8b77c0000",
"_score": 0.2876821,
"_source": {
"name": "Bootstrap开发框架",
"description": "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较
为广泛。 此开发框架包含了大量的CSS、 JS程序代码, 可以帮助开发者( 尤其是不擅长页面开发的程序人员) 轻松的实现
一个不受浏览器限制的精美界面效果。 ",
"studymodel": "201001"
}
}]
}
}
took:本次操作花费的时间,单位为毫秒。
timed_out:请求是否超时 _shards:说明本次操作共搜索了哪些分片
hits:搜索命中的记录
hits.total : 符合条件的文档总数
hits.hits :匹配度较高的前N个文档
hits.max_score:文档匹配得分,这里为最高分
_score:每个文档都有一个匹配度得分,按照降序排列。
_source:显示了文档的原始内容。
在添加文档时会进行分词,索引中存放的就是一个一个的词(term),当你去搜索时就是拿关键字去匹配词,最终 找到词关联的文档。
测试当前索引库使用的分词器: post 发送:localhost:9200/_analyze {"text":"测试分词器,后边是测试内容:spring cloud实战"}
会发现分词的效果将 “测试” 这个词拆分成两个单字“测”和“试”,这是因为当前索引库使用的分词器对中文就是单字 分词。
使用IK分词器可以实现对中文分词的效果。 下载IK分词器:(Github地址:https://github.com/medcl/elasticsearch-analysis-ik)
目前最新版本是IK v7.16.2,大家自行更具es来选对应的版本
下载zip:
发送:post localhost:9200/_analyze {"text":"测试分词器,后边是测试内容:spring cloud实战","analyzer":"ik_max_word"
ik分词器有两种分词模式:ik_max_word和ik_smart模式。
如果要让分词器支持一些专有词语,可以自定义词库。 iK分词器自带一个main.dic的文件,此文件为词库文件。在具体安装es的plugins/ik/config 下
在上边的目录中新建一个my.dic文件(注意文件格式为utf-8(不要选择utf-8 BOM)) 可以在其中自定义词汇: 比如定义: 配置文件中配置my.dic,