Elasticsearch简称为es,是一个开源的高扩展的分布式全文检索引擎,近实时的存储、检索数据。可以扩展到上百台服务器,处理PB级别的数据。使用Lucene作为核心来实现所有索引和搜索的功能,通过简单的restful api隐藏Lucene的复杂性,事全文搜索变得简单。
Elasticsearch是一个实时分布式搜索和分析引擎。
Solr是Apache下的一个顶级开源项目,采用java开发,基于Lucene的全文搜索服务器,封装了Lucene,solr提供了比Lucene更丰富的查询语言,可配置、可扩展,对索引、搜索性能进行了优化。
Solr可以在jetty、Tomcat等容器中运行。
Solr生成索引,使用post方法向solr服务器发送一个描述field及其内容的xml文档,solr根据xml文档添加、删除、更新索引。
搜索查找发送http get请求,对solr返回的xml、json等格式的查询返回结果进行解析,组织页面布局。
Lucene是Apache软件基金会的一个子项目,是一个开放源代码的全文检索引擎工具包,为开发人员提供一个简单易用的工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。
(1)对已有的,已存在的数据进行搜索时,solr更快。
(2)当实时建立索引时,solr会产生io堵塞,查询性能较差,elasticsearch具有明显的优势。
(3)随着数据量的增加,solr的搜索效率会变得更低,而elasticsearch却没有明显的变化。
(4)Elasticsearch开箱即用,解压既可以使用,solr安装稍微有点复杂。
(5)Solr使用zookeeper进行分布式管理,而elasticsearch自身带有分布式协调功能功能。
(6)Solr支持的数据格式,json、xml、CSV。Elasticsearch支持json数据格式。
(7)Solr官方提供的功能多。Elasticsearch注重核心功能,可以通过第三方插件扩展高级功能,例如:使用kibana提供图形化界面。
(8)Solr查询快,插入、删除时更新索引慢。Elasticsearch建立索引快,实时性查询快。
elasticsearch界面工具,一般用来查看数据记录。
下载地址:https://github.com/mobz/elasticsearch-head/
安装、启动命令:
cd elasticsearch-head
npm install
npm run start
elasticsearch-7.15.0\config\elasticsearch.yml
添加内容,解决跨域访问。
http.cors.enabled: true
http.cors.allow-origin: "*"
kibana是一个针对elasticsearch的开源分析、可视化平台,用来搜索、查看交互存储在elasticsearch索引中的数据。使用kibana可以通过各种图表进行高级数据分析及展示。Kibana让海量数据跟容易理解。操作简单,基于浏览器用户界面可以快速创建仪表板dashboard实时显示elasticsearch查询动态。
kibana-7.15.1\config
kibana.yml文件,修改配置内容。
i18n.locale: "zh-CN"
关系型数据库
|
数据库database
|
Elasticsearch |
|
数据库database
|
索引indices |
|
表tables
|
types |
|
行rows
|
documents |
|
字段columns
|
fields |
Elasticsearch集群中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档中又包含多个字段(行)。
物理设计。
Elasticsearch将每个索引划分成多个分片,每个分片在集群中的不同服务器间迁移。
逻辑设计。
一个索引类型中,包含多个文档。查找某一篇文档,索引-->类型-->文档ID。
文档document:
Elasticsearch是面向文档的,索引和搜索数据的最小单位是文档。
一个文档就是一条数据。
类型:
类型是文档的逻辑容器,就像关系型数据库一样,表格是行的容器。
类型中对于字段的定义称为映射,字段类型mapping。例如:name映射为字符串类型。
文档是无模式的,ES可以根据数据值自动识别字段类型,也可以提前手动定义好映射。
索引:
索引时映射类型的容器,是一个非常大的文档集合,索引存储了映射类型的字段和其他设置。被存储到各个分片上。
一个集群至少一个节点,一个节点就是一个elasticsearch进程。创建索引,默认有5个primary shard主分片,每一个主分片会有一个replica shard副本分片。
一个分片是一个Lucene索引,一个包含倒排索引的文件目录,倒排索引的结构使得elasticsearch在不扫描全部文档的情况下,就可以知道哪些文档包含特定的关键字。
倒排索引:
ES使用的是一种称为倒排索引的结构,采用Lucene倒排索引作为底层。适用于快速的全文搜索,一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。
创建倒排索引,将每个文档拆分成独立的词(词条或tokens),创建一个包含所有不重复的词条的排序列表,然后列出每个词条出现在哪个文档。
分词:把一段中文或者英文划分成一个一个的关键字,在搜索的时候会把自己的信息进行分词,把数据库中或索引库中的数据进行分词,进行一个匹配操作。
默认的中文分词是将每个汉字看成一个词。
例如:“超级喜欢三体”,会被分为“超”“级”“喜”“欢”“三”“体”。
GET _analyze
{
"text": "超级喜欢三体"
}
这不符合需要,所以需要安装中文分词器IK来解决这个问题。
IK下载地址:Releases · medcl/elasticsearch-analysis-ik · GitHub
下载elasticsearch对应版本的IK分词器,版本一定要对应。在elasticsearch\plugins\目录新建一个ik文件夹,解压复制到ik文件夹中。然后重启ES。
例如:下载elasticsearch-7.15.0的IK分词器elasticsearch-analysis-ik-7.15.0.zip
查看ES安装了哪些插件命令elasticsearch-plugin list。
\elasticsearch-7.15.0\bin>elasticsearch-plugin list
IK提供了两个分词算法:ik_smart和ik_max_word。
(1)ik_smart会做最粗粒度的拆分,已被分出的词语将不会再次被其它词语占有。为最少切分,最细粒度只切一个,最少粒度切分,没有重复的数据,按断点打开,打成所能理解的话。
例如:
GET _analyze
{
"analyzer": "ik_smart",
"text": "中华人民共和国"
}
GET _analyze
{
"analyzer": "ik_smart",
"text": "四川省广汉市三星堆博物馆"
}
(2)ik_max_word会将文本做最细粒度的拆分,尽可能多的拆分出词语。为最细粒度划分,穷尽词库的可能,穷尽字典的可能。
例如:
GET _analyze
{
"analyzer": "ik_max_word",
"text": "中华人民共和国"
}
GET _analyze
{
"analyzer": "ik_max_word",
"text": "四川省广汉市三星堆博物馆"
}
如果某个词被拆开了,不希望拆开,需要自己加到分词器的词典中。
例如:
GET _analyze
{
"analyzer": "ik_smart",
"text": "超级喜欢三体"
}
GET _analyze
{
"analyzer": "ik_max_word",
"text": "超级喜欢三体"
}
“三体”这个词被拆开了,不想拆开,在词库中加入这个词。
在\elasticsearch-7.15.0\plugins\ik\config文件夹中,新建一个文件zidingyi.dic,文件名任意命名,在里面添加“三体”这个词语。
在IKAnalyzer.cfg.xml文件中配置这个文件。
重启elasticsearch。
显示效果如下,显示“三体”变成一个词语。
一种软件架构风格,提供了一组设计原则和约束条件。不是一个标准。基于这个风格设计的软件可以更简洁,更有层次,易于实现缓存等机制。主要用于客户端和服务器交互类的程序。
|
方法Method
|
地址url
|
描述 |
|
PUT
|
索引名称/类型名称/文档id
|
创建文档,指定文档id。 |
|
POST
|
索引名称/类型名称
|
创建文档,随机文档id。 |
|
POST
|
索引名称/类型名称/文档id/_update
|
修改文档。 |
|
POST
|
索引名称/类型名称/_search
|
查询所有数据。 |
|
DELETE
|
索引名称/类型名称/文档id
|
删除文档。 |
|
GET
|
索引名称/类型名称/文档id
|
通过文档id查询文档。 |
PUT /索引名称/类型名称/文档id
8.0会去掉type类型名称。
在 5.X 版本中,一个 index 下可以创建多个 type;
在 6.X 版本中,一个 index 下只能存在一个 type;
在 7.X 版本中,直接去除了 type 的概念,就是说 index 不再会有 type。
PUT /test1/type1/1
{
"name": "新新",
"age": 18
}
字符串类型:text、keyword。
数值类型:long、integer、short、byte、double、float、half、float、scaled、float。
日期类型:date。
布尔值类型:boolean。
二进制类型:binary。
例如:
PUT /test2
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "long"
},
"birthday": {
"type": "date"
}
}
}
}
查看索引具体信息。
例如:
GET /test1
ES 8.0会弃用类型名称。类型名称默认为_doc。
如果创建文档时,没有指定文档字段类型,ES会默认配置字段类型。
例如:
PUT /test3/_doc/1
{
"name": "新新1",
"age": 18,
"birth": "2021-10-31"
}
查看记录。
GET /test3/_doc/1
查看索引信息。
GET /test3
使用_cat查看ES信息。
查看ES健康状况。
GET /_cat/health
查看ES索引。
GET /_cat/indice
使用PUT方式覆盖数据,覆盖时需要全部字段,否则会丢失字段数据,会生成一个新的文档对象。
PUT /test3/_doc/1
{
"name": "新新2",
"age": 18,
"birth": "2021-10-31"
}
使用POST方式修改索引,可以指定修改某个字段,POST时带_update。
POST /test3/_doc/1/_update
{
"doc": {
"name": "新新3"
}
}
使用DELETE命令实现删除。
删除索引。
DELETE /test1
删除document文档,删除记录。
DELETE /test3/_doc/1
例如:
PUT /corp/user/1
{
"name": "张三",
"age": 18,
"desc": "法外狂徒。",
"tags": ["交友", "旅游", "暖男"]
}
PUT /corp/user/2
{
"name": "李四",
"age": 18,
"desc": "一顿操作猛如虎,一看工资2500。",
"tags": ["技术宅", "温暖", "直男"]
}
PUT /corp/user/3
{
"name": "王五",
"age": 18,
"desc": "我去年买了个表。",
"tags": ["靓女", "旅游", "唱歌"]
}
PUT /corp/user/4
{
"name": "张三山",
"age": 3,
"desc": "疯狂的石头。",
"tags": ["交友", "旅游", "暖男"]
}
GET /corp/user/1
使用PUT方式覆盖修改数据。
例如:
PUT /corp/user/3
{
"name": "王五",
"age": 18,
"desc": "我去年买了个表,去年买了个表,年买了个表,买了个表,了个表,个表,表。",
"tags": ["靓女", "旅游", "唱歌"]
}
使用POST方式修改数据,推荐的方式。需要带_update。
例如:
POST /corp/user/3/_update
{
"doc": {
"name": "刘六"
}
}
(1)简单搜索。
例如:
查询某一条记录,某一个document文档。
GET /corp/user/3
查询所有记录。
GET /corp/user/_search
根据某个字段查询。
GET /corp/user/_search?q=name:张
根据某个字段查询。
GET /corp/user/_search?q=name:李四
例如:
GET /corp/user/_search
{
"query": {
"match": {
"name": "张三"
}
}
}
返回:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.4523083,
"hits" : [
{
"_index" : "corp",
"_type" : "user",
"_id" : "1",
"_score" : 1.4523083,
"_source" : {
"name" : "张三",
"age" : 18,
"desc" : "法外狂徒。",
"tags" : [
"交友",
"旅游",
"暖男"
]
}
},
{
"_index" : "corp",
"_type" : "user",
"_id" : "4",
"_score" : 1.2199391,
"_source" : {
"name" : "张三山",
"age" : 3,
"desc" : "疯狂的石头。",
"tags" : [
"交友",
"旅游",
"暖男"
]
}
}
]
}
}
响应返回解析。
Hits包括:索引和文档的信息;查询的结果总数量;查询出来的具体的文档;可以遍历数据。
_score分数,符合搜索结果的程度,匹配度。
查询返回某几个字段,结果过滤。
例如:
GET /corp/user/_search
{
"query": {
"match": {
"name": "张三"
}
},
"_source": ["name", "desc"]
}
使用sort排序,desc降序,asc升序。
GET /corp/user/_search
{
"query": {
"match": {
"name": "张三"
}
},
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
from从第几个数据开始查询,数据下标从0开始。size每页显示几条记录,返回多少条数据。
GET /corp/user/_search
{
"query": {
"match": {
"name": "张三"
}
},
"sort": [
{
"age": {
"order": "desc"
}
}
],
"from": 0,
"size": 1
}
must,所有的条件都需要符合,相当于sql中的and。
例如:
GET /corp/user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "张三"
}
},
{
"match": {
"age": 3
}
}
]
}
}
}
should,满足其中一个条件即可,相当于sql中的or。
GET /corp/user/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"name": "张三"
}
},
{
"match": {
"age": 3
}
}
]
}
}
}
must_not,不等于,不符合条件的都查询出来,相当于sql中的not。
例如:
GET /corp/user/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"name": "张三"
}
},
{
"match": {
"age": 3
}
}
]
}
}
}
查询符合某个区间的记录。
gt:大于。
lt:小于。
gte:大于等于。
lte:小于等于。
例如:
GET /corp/user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "张三"
}
}
],
"filter": [
{
"range": {
"age": {
"gt": 10,
"lt": 20
}
}
}
]
}
}
}
多个条件使用空格隔开,只要满足其中一个条件就可以被查出,可以通过分值作判断。
GET /corp/user/_search
{
"query": {
"match": {
"tags": "女 唱歌"
}
}
}
GET /corp/user/_search
{
"query": {
"match": {
"tags": "男 技术"
}
}
}
term查询是直接通过倒排索引指定的词条进行精确的查找。
关于分词:
term,因为使用倒排索引,直接查询精确的记录。
match,使用分词器解析,先分析文档,然后通过分析的文档进行查询。
text与keyword两个类型。
text字段类型被分词器普通解析。
keyword不分词,内容整体作为一个值。字段类型不会被分词器解析,在存储的过程中没有分词,keyword字段不会进行分词,当做一个整体,不可拆分。避免使用keyword字段进行全文搜索(full-text)。改为使用文本(text)字段类型。
例如:
建立索引。
PUT /testdb
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"desc": {
"type": "keyword"
}
}
}
}
添加两条数据。
PUT /testdb/_doc/1
{
"name": "新新说脱口秀 name",
"desc": "新新说脱口秀 desc"
}
PUT /testdb/_doc/2
{
"name": "新新说脱口秀 name",
"desc": "新新说脱口秀 desc2"
}
分词器普通解析情况,被拆分成了多个。
GET _analyze
{
"analyzer": "standard",
"text": "新新说脱口秀 name"
}
keyword不会被分词器解析,作为一个整体。
GET _analyze
{
"analyzer": "keyword",
"text": "新新说脱口秀 name"
}
查询解析情况。
name字段是text类型,查询时会被拆分。
GET /testdb/_search
{
"query": {
"term": {
"name": "新"
}
}
}
desc字段是keyword类型,查询时不会被拆分,当作一个整体查询。
GET /testdb/_search
{
"query": {
"term": {
"desc": "新新说脱口秀 desc"
}
}
}
例如:
添加两条数据。
PUT /testdb/_doc/3
{
"t1": "11",
"t2": "2020-11-11"
}
PUT /testdb/_doc/4
{
"t1": "22",
"t2": "2021-11-11"
}
多值精确查询。
GET /testdb/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"t1": "11"
}
},
{
"term": {
"t1": "22"
}
}
]
}
}
}
搜索相关的结果可以高亮显示,默认使用HTML的<em></em>标签显示高亮。
例如:
GET /corp/user/_search
{
"query": {
"match": {
"name": "张三"
}
},
"highlight": {
"fields": {
"name": {}
}
}
}
使用自己定义的HTML标签显示高亮。
例如:
GET /corp/user/_search
{
"query": {
"match": {
"name": "张三"
}
},
"highlight": {
"pre_tags": "<p class='key' style='color:red'",
"post_tags": "</p>",
"fields": {
"name": {}
}
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/xinxin19881112/article/details/121240371
内容来源于网络,如有侵权,请联系作者删除!