第一次在掘金发表文章,有些不足之处,求勿喷!求勿喷!求勿喷! 身为一个前端,竟然搞es缘由在于咱们公司内部的wiki文档全栈项目的使用,因为日益增多的文章和想要全文检索的需求,而且本来的mongodb数据库,查询全文检索时特别慢,才引入了es。 车300工具平台,项目目前还没公开出来,预计2021年公开。html
一个叫 Doug Cutting
的美国工程师迷上了搜索引擎,他作了一个用于文本搜索的函数库(软件功能组件),命名为Lucene
。Lucene
是JAVA
写的,目标是为各类中小型应用软件加入全文检索功能。由于好用且开源,很是受程序员欢迎。 早期是由这我的本身维护,后期作大后,2001年末,成为Apache
软件基金会jakarta
项目的一个子项目。前端
Lucene
是一个信息检索工具包,jar包,不包含搜索引擎系统! 包含了:索引结构、读写索引的工具、排序、搜索规则...工具类!java
elasticSearch
是基于Lucene
作了一些封装和加强。es
是一个开源的、高拓展的、分布式、全文检索引擎。诞生于21世纪大数据时代。(Restful Api)。2016年超过solr
,成为排名第一个的搜索引擎类应用。node
多年前,一个叫作Shay Banon
刚结婚不久的失业开发者,因为妻子要去伦敦学习厨师,他就跟老婆一块儿去了,在他找工做的过程当中,为了给妻子构建一个食谱搜索引擎,他就开始使用Lucene
工具包开发。因为直接使用原生工具包很是麻烦,因而他就开始抽象化Lucene
代码写本身的封装,后来他在找到工做后又重写了 本身的封装,并命名为elasticsearch
。 再后来,2010年2月,第一个公开版es
发布,es
在短期内瞬间成为当时 github
上最受欢迎的项目之一,一家主营es
的公司就此成立,他们一边开发新功能,一边提供商用,并永远开源
, 遗憾的是,Shay的妻子依然在等待食谱搜索....mysql
1)百度,谷歌。咱们能够经过输入一些关键字去搜索咱们须要的东西。 2)互联网的搜索:电商网站。招聘网站。新闻网站。各类APP(百度外卖,美团等等) 3)windows系统的搜索等等linux
总结:搜索无处不在。经过一些关键字,给咱们查询出来跟这些关键字相关的信息git
全文检索是指计算机索引程序经过扫描文章中的每个词,对每个词创建一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先创建的索引
进行查找,并将查找的结果反馈给用户的检索方式。这个过程相似于经过字典中的检索字表查字的过程。程序员
使用 java 语言开发的一套开源的全文搜索引擎 用于搜索、日志管理、安全分析、指标分析、业务分析、应用性能监控等多个领域 底层基于
Lucene
开源库开发,提供restAPI
,能够被任何语言调用 支持分布式部署,可水平扩展 更新迭代快、社区活跃、文档丰富(2020年9月写的这篇文章是7.9.1,而如今11月已经7.10.x了)github
连接: elasticsearch下载redis
ik分词器是一个github项目,能够选择git clone 或者 直接download zip
为了方便演示,这边是windows系统下的教程,linux后续推出如何发布线上等等。
bin 是启动目录
config 配置文件
--- log4j2 日志配置文件
--- jvm.options java虚拟机相关配置
--- elasticsearch.yml elasticsearch配置文件,默认 9200 端口!
lib 相关jar包
logs 日志
modules 相关模块
plugins 插件如ik
复制代码
直接访问 bin
目录下 elasticsearch.bat
git clone https://github.com/mobz/elasticsearch-head.git
复制代码
进入目录后
cnpm install
复制代码
访问 localhost:9100
, 发现跨域问题
去es config
目录 的 elasticsearch.yml
添加跨域配置
http.cors.enabled: true
http.cors.allow-origin: "*"
复制代码
*
表明全部人均可以访问,实际正式环境不能够这样配置
重启 elasticsearch
这时再访问 localhost:9100
便可
了解ELK工程师 ELK是 Elasticsearch Logstash Kibana 三大开源库的简称,市面上也称为 Elastic Stack。其中Elasticsearch是一个基于Lucene、分布式、经过Restful方式进行交互的近实时搜索平台框架。像百度、谷歌这种大数据全文搜索引擎的场景均可以使用es这做为底层支持框架,可见es提供的搜索能力确实强大,Logstash 是中央数据流引擎,用于从不一样目标(文件/数据存储/MQ)收集的不一样格式数据,通过过滤后只支持输出到不一样目的地(文件/MQ/redis/es等)。Kibana是一个es可视化工具,提供了实时分析的能力。
收集清洗数据 ---> 搜索,存储 --->Kibana
要保证Kibana版本和es保持一致
kibana-7.9.1-windows-x86_64\bin
目录下的 kibana.bat
| 
|_
复制代码
访问 5601端口便可访问
ps:开发工具!(postman等等其余的)
去配置文件D:\tools\kibana-7.9.1-windows-x86_64\config\kibana.yml
中修改
i18n.locale: "zh-CN"
复制代码
es是面向文档的非关系数据库
关系型数据库 | es |
---|---|
数据库 | 索引 |
表 | types(慢慢被弃用了,7.x.x版本使用统一的_doc,并在查询命令中能够省略) |
行 | documents(文档) |
字段 | fields |
es是面向文档的,
尽管咱们能够随意新增忽略某个字段,可是每一个字段的类型很是重要,好比一个年龄类型字段,能够是字符串也能够是整数,由于es中会保存字段和类型之间的映射以及其余的设置,这种映射具体到每一个映射的每种类型,这也是为何在es中,类型有时候也称为映射类型。
一个文档主要元素大体包含如下内容:
1. _index: 文档所属的索引名
2. _type: 文档所属的类型名(废弃品)
3. _id: 文档的惟一ID
4. _source: 文档存储的 Json 数据
5. _version:文档的版本信息
6. _score: 相关性打分
复制代码
类型是文档的逻辑容器,就像关系型数据库同样,表格是行的容器。
最直接的理解就是数据库!
一个集群至少有一个节点,而一个节点就是一个es进程,节点能够有多个索引(默认的),若是你建立索引,那么索引将会有5个分片(primary shard,又称主分片)构成的,每个主分片会有一个副本(replica shard,又称复制分片)
由于不是专职作这个的,因此这里关于这些东西就一带而过了。。。,小白入门不须要了解太多底层吧
es使用的是一种称为倒排索引的结构,采用Lucene倒排索引做为底层,这种结构适用于快速的全文索引,一个索引由文档中全部的不重复的列表构成,对于每个词,都有一个包含它的文档列表。例如,如今有两个文档,每一个文档包含以下内容:
Study every day, good good up, to forever # 文档一
To forever, study every day, good good up # 文档二
复制代码
为了建立倒排索引,咱们要将每一个文档拆分红独立的词(词条),而后建立一个包含全部不重复词条的排序列表,而后列出每一个词条出如今哪一个文档
如今咱们要去搜索 to forever 只须要查看包含每一个词条的文档
这里产生了权重!
总结:倒排索引帮咱们彻底过滤掉了一些无用的数据,帮咱们提升了效率
一、索引(数据库) 二、字段类型(mapping) 三、文档 四、分片(了解,Lucene索引)
分词就是把一段中文或者英文划分为一个个关键字,咱们在搜索的时候会把本身的信息进行分词,会把数据库中的或者索引库中的数据进行分词,而后进行一个匹配操做作,默认的中文分词是将每个字当作一个词,好比“我爱育仪”会被分红“我”“爱”“育”“仪”,这里显然是不合理的,因此咱们须要安装中文的分词器。 IK提供了两个分词算法:ik_smart
和 ik_max_word
,其中 ik_smart
是最少切分,ik_max_word
是最细粒度划分!
附件中有IK分词器的安装包 一、安装 二、直接解压到es安装目录的plugin
目录中命名为ik
三、重启es
验证 分词器是否安装完成, 四、使用 elasticsearch-plugin
五、用kibana测试!
ik_smart 最少划分
ik_max_word 最多划分
两种分词器使用的最佳实践是:索引时用ik_max_word,在搜索时用ik_smart。 即:索引时最大化的将文章内容分词,搜索时更精确的搜索到想要的结果。
一、ik_max_word
会将文本作最细粒度的拆分,好比会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、大会堂、大会、会堂等词语。
二、ik_smart 会作最粗粒度的拆分,好比会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。
这种本身须要的词,须要咱们本身加上咱们的分词器中,才会实现真正的分词
D:\tools\elasticsearch-7.9.1\plugins\ik\config\IKAnalyzer.cfg.xml
(这是个人路径,别人和我不同的) 在这个目录下修改
| 
|_
复制代码
在elasticsearch-7.9.1\plugins\ik\config
目录下新建 自定义的词典例如: 一、新建yuyi.dic
二、在 该文件中写入 三、在下图位置加上本身的配置文件名
四、重启es 五、再次测试
GET _analyze
{
"analyzer": "ik_smart",
"text": "超级喜欢育仪讲"
}
复制代码
返回值发生了变化
{
"tokens" : [
{
"token" : "超级",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "喜欢",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "育仪",
"start_offset" : 4,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "讲",
"start_offset" : 6,
"end_offset" : 7,
"type" : "CN_CHAR",
"position" : 3
}
]
}
复制代码
之后须要本身配置,就须要本身在分词中设置便可
这是一种架构风格而不是标准,他用于客户端与服务器交互 类的软件,基于这个风格设计软件能够更简洁、更有层次等。
method | url地址 | 描述 |
---|---|---|
PUT | localhost:9200/索引名称/类型名称/文档id | 建立文档(指定文档id) |
POST | localhost:9200/索引名称/类型名称 | 建立文档(随机文档id) |
POST | localhost:9200/索引名称/_update/文档id | 修改文档 |
DELETE | localhost:9200/索引名称/类型名称/文档id | 删除文档 |
GET | localhost:9200/索引名称/类型名称/文档id | 经过文档id查询文档 |
POST | localhost:9200/索引名称/类型名称/_search | 查询全部数据 |
PUT /test1/type1/1
{
"name":"育仪",
"age":24
}
复制代码
类型名将来在 8版本中会被删除
PUT /test3/_doc/1
{
"name":"育仪分享会",
"age":24,
"birth":"1996-09-12"
}
复制代码
这里的_doc是将来es官方指定的类型,将来将去掉类型名称,统一为一个系统指定的_doc
若是咱们没有指定 文档类型,es默认会帮咱们指定类型
测试
PUT /test2
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"age":{
"type": "long"
},
"birthday":{
"type": "date"
}
}
}
}
复制代码
返回上图则成功
mappings、properties为指定字段类型的必须格式,内部的name、age、birthday为用户想要的类型,相似mysql的建表。
GET /test2
复制代码
能够经过get请求,直接获取test2索引的所有信息
查看数据库健康值
GET _cat/health
复制代码
查看es不少信息
GET _cat/indices?v
复制代码
等等还有不少
修改提交仍是使用PUT 而后覆盖便可!(曾经的方法)
PUT /test3/_doc/1
{
"name":"育仪分享会20200921",
"age":24,
"birth":"1996-09-12"
}
复制代码
这种修改更新方式是总体修改,一旦丢掉数据则会产生修改错误的字段
更新的方法(新的)
POST /test3/_update/1
{
"doc":{
"name":"育仪大魔王"
}
}
复制代码
更新成功,再调用查看方法便可发现就
name
字段发生了变化。 值得注意的是 doc
是固定写法
删除整个索引
DELETE /test1
复制代码
返回值:
删除一条数据
Delete /test3/_doc/1
复制代码
使用RESTFUL风格是咱们ES推荐你们使用的!
一、先建立一个索引并加入数据
PUT /yuyi/_doc/1
{
"name":"朱育仪",
"age":24,
"desc":"我明天就要分享了,我慌的一批",
"tags":["技术宅","温暖","直男"]
}
PUT /yuyi/_doc/2
{
"name":"张三",
"age":24,
"desc":"我是张三",
"tags":["傻叉","旅游","渣男"]
}
PUT /yuyi/_doc/3
{
"name":"李四",
"age":30,
"desc":"我是李四",
"tags":["靓女","旅游","唱歌"]
}
复制代码
二、查询 查询yuyi索引下的 1号人物
GET /yuyi/_doc/1
复制代码
三、搜索 条件查询 获取一号用户的
GET /yuyi/_doc/_search?q=name:朱育仪
复制代码
咱们发现 上图中有一个 _score这个字段,若是有多条数据,匹配度越高则分值越高
略复杂的查询方式
GET /yuyi/_doc/_search
{
"query":{
"match":{
"name":"朱育仪"
}
}
}
复制代码
仍是同样返回上文图片的返回值
GET /yuyi/_doc/_search
{
"query":{
"match":{
"name":"朱育仪"
}
},
"_source":["name","age"]
}
复制代码
![]
咱们以后使用nodejs 操做es,全部的方法和对象就是这里面的key!
GET /yuyi/_doc/_search
{
"query":{
"match_all":{}
},
"sort":[
{
"age":{
"order":"desc"
}
}
]
}
复制代码
match_all
表明全文匹配 sort
字段是个数组里面传递对象用来排序,上面的语句是对age
进行排序,order
表明排序规则“desc
降序 asc
升序” 有了固定的排序后,_score
分值就没了。
GET /yuyi/_doc/_search
{
"query":{
"match_all":{
}
},
"sort":[
{
"age":{
"order":"desc"
}
}
],
"from":0,
"size":2
}
复制代码
from
表明了从第几个开始,size
表示每页多少个
GET /yuyi/_doc/_search
{
"query":{
"bool":{
"must":[
{
"match":{
"name":"育仪"
}
},
{
"match":{
"age":24
}
}
]
}
}
}
复制代码
采用 bool字段, 内部可选参数:must(必须包含)must_not(必须不包含)should(有一个就能够了)(minimum_should_match: 用来控制至少匹配多少个should匹配的) 上面匹配的是 name
包含 育仪
字段 age
是 24
的数据
should查询测试
GET /yuyi/_doc/_search
{
"query":{
"bool":{
"should":[
{
"match":{
"name":"育仪"
}
},
{
"match":{
"age":24
}
}
]
}
},
"from":0,
"size":2
}
复制代码
会返回只要符合name 是育仪 或者 age是 24的就能够了。
GET /yuyi/_doc/_search
{
"query":{
"bool":{
"must":[
{
"match":{
"name":"育仪"
}
}
],
"filter":{
"range":{
"age":{
"gte":10,
"lte":30
}
}
}
}
}
}
复制代码
经过 filter
查询过滤数据,将过滤age
大于等于10小于等于30的 gt
大于 lt
小于 gte
大于等于 lte
小于等于
GET /yuyi/_doc/_search
{
"query":{
"match":{
"tags":"男"
}
}
}
复制代码
想要匹配多个条件直接空格隔开便可
GET /yuyi/_doc/_search
{
"query":{
"match":{
"tags":"男 技术"
}
}
}
复制代码
咱们发现只要匹配到了这两个词中的任意一个,就会被返回,然而第二条数据并不太符合技术
这个关键词。 这个时候能够经过返回值中的分值进行基本的判断,匹配程度。
term 直接经过倒排索引精确查找的
关于分词,term会直接查询精确值,match会使用分词器解析,再经过分析的文档查询
两个类型 text keyword text类型会被分词器进行解析 keyword不会被分割解析
测试代码一个一个请求
PUT testdb
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"desc":{
"type": "keyword"
}
}
}
}
PUT testdb/_doc/1
{
"name":"育仪准备分享会",
"desc":"育仪准备分享会"
}
PUT testdb/_doc/2
{
"name":"育仪准备分享会 name",
"desc":"育仪准备分享会 desc"
}
复制代码
查看分词结果
GET _analyze
{
"analyzer": "keyword",
"text":"育仪准备分享会"
}
复制代码
如上图所示,keyword形式将再也不进行分词
GET _analyze
{
"analyzer": "ik_smart",
"text":"育仪准备分享会"
}
复制代码
使用ik分词器后是这个结果
精准查询的测试
GET /testdb/_search
{
"query":{
"term":{
"name":"育"
}
}
}
复制代码
查询name
中含有育
的数据,因为name属性是text类型,会被分词
GET /testdb/_search
{
"query":{
"term":{
"desc":"育"
}
}
}
复制代码
此时咱们发现 desc
查询育
字时无值,因为咱们使用了keyword
类型 ,因此咱们必须使用育仪准备分享会
所有文字才能匹配到值。以下方的测试
GET /testdb/_search
{
"query":{
"term":{
"desc":"育仪准备分享会"
}
}
}
复制代码
总结:keyword
不会被分词器解析
测试代码(插入多个数据)
PUT testdb/_doc/3
{
"t1":"22",
"t2":"2020-09-23"
}
PUT testdb/_doc/4
{
"t1":"33",
"t2":"2020-09-24"
}
复制代码
使用 term
精确查询多个值
GET /testdb/_search
{
"query":{
"bool":{
"should": [
{
"term":{
"t1":"22"
}
},
{
"term":{
"t1":"33"
}
}
]
}
}
}
复制代码
GET /yuyi/_search
{
"query":{
"match":{
"name":"育仪"
}
},
"highlight": {
"fields": {
"name": {}
}
}
}
复制代码
经过 上文方式能够实现高亮,highlight``fields
为固定写法
咱们这里不想用em
标签 想用其余的
GET /yuyi/_search
{
"query":{
"match":{
"name":"育仪"
}
},
"highlight": {
"pre_tags": "<p class='myClassName' style='color:red'>",
"post_tags": "</p>",
"fields": {
"name": {}
}
}
}
复制代码
这里使用
pre_tags
post_tags
来自定义标签高亮
Elasticsearch 之(24)IK分词器配置文件讲解以及自定义词库
还有不少借鉴其余的出处忘记了。。。