Elasticsearch学习笔记之二

x33g5p2x  于2021-12-06 转载在 ElasticSearch  
字(11.7k)|赞(0)|评价(0)|浏览(325)

一、elasticsearch概述。

Elasticsearch简称为es,是一个开源的高扩展的分布式全文检索引擎,近实时的存储、检索数据。可以扩展到上百台服务器,处理PB级别的数据。使用Lucene作为核心来实现所有索引和搜索的功能,通过简单的restful api隐藏Lucene的复杂性,事全文搜索变得简单。

Elasticsearch是一个实时分布式搜索和分析引擎。

二、Solr与elasticsearch的对比及选型。

1、solr概述。

Solr是Apache下的一个顶级开源项目,采用java开发,基于Lucene的全文搜索服务器,封装了Lucene,solr提供了比Lucene更丰富的查询语言,可配置、可扩展,对索引、搜索性能进行了优化。

Solr可以在jetty、Tomcat等容器中运行。

Solr生成索引,使用post方法向solr服务器发送一个描述field及其内容的xml文档,solr根据xml文档添加、删除、更新索引。

搜索查找发送http get请求,对solr返回的xml、json等格式的查询返回结果进行解析,组织页面布局。

2、Lucene概述。

Lucene是Apache软件基金会的一个子项目,是一个开放源代码的全文检索引擎工具包,为开发人员提供一个简单易用的工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。

3、Solr与elasticsearch的适用场景,以及比较。

(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建立索引快,实时性查询快。

4、elasticsearch-head。

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概述。

1、kibana概述。

kibana是一个针对elasticsearch的开源分析、可视化平台,用来搜索、查看交互存储在elasticsearch索引中的数据。使用kibana可以通过各种图表进行高级数据分析及展示。Kibana让海量数据跟容易理解。操作简单,基于浏览器用户界面可以快速创建仪表板dashboard实时显示elasticsearch查询动态。

2、kibana汉化。

kibana-7.15.1\config

kibana.yml文件,修改配置内容。

i18n.locale: "zh-CN"

四、ES核心概念理解。

1、ES与关系型数据库对比。

关系型数据库 

|
数据库database
|
Elasticsearch |
|
数据库database
|
索引indices |
|
表tables
|
types |
|
行rows
|
documents |
|
字段columns
|
fields |

Elasticsearch集群中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档中又包含多个字段(行)。 

2、ES物理设计、逻辑设计。

物理设计。

Elasticsearch将每个索引划分成多个分片,每个分片在集群中的不同服务器间迁移。

逻辑设计。

一个索引类型中,包含多个文档。查找某一篇文档,索引-->类型-->文档ID。

文档document:

Elasticsearch是面向文档的,索引和搜索数据的最小单位是文档。

一个文档就是一条数据。

类型:

类型是文档的逻辑容器,就像关系型数据库一样,表格是行的容器。

类型中对于字段的定义称为映射,字段类型mapping。例如:name映射为字符串类型。

文档是无模式的,ES可以根据数据值自动识别字段类型,也可以提前手动定义好映射。

索引:

索引时映射类型的容器,是一个非常大的文档集合,索引存储了映射类型的字段和其他设置。被存储到各个分片上。

一个集群至少一个节点,一个节点就是一个elasticsearch进程。创建索引,默认有5个primary shard主分片,每一个主分片会有一个replica shard副本分片。

一个分片是一个Lucene索引,一个包含倒排索引的文件目录,倒排索引的结构使得elasticsearch在不扫描全部文档的情况下,就可以知道哪些文档包含特定的关键字。

倒排索引:

ES使用的是一种称为倒排索引的结构,采用Lucene倒排索引作为底层。适用于快速的全文搜索,一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。

创建倒排索引,将每个文档拆分成独立的词(词条或tokens),创建一个包含所有不重复的词条的排序列表,然后列出每个词条出现在哪个文档。

五、IK分词器插件。

1、为什么需要IK分词器。

分词:把一段中文或者英文划分成一个一个的关键字,在搜索的时候会把自己的信息进行分词,把数据库中或索引库中的数据进行分词,进行一个匹配操作。

默认的中文分词是将每个汉字看成一个词。

例如:“超级喜欢三体”,会被分为“超”“级”“喜”“欢”“三”“体”。 

GET _analyze
{
  "text": "超级喜欢三体"
}

这不符合需要,所以需要安装中文分词器IK来解决这个问题。

 2、安装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

3、使用IK分词器。

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": "四川省广汉市三星堆博物馆"
}

4、自定义词库,配置IK扩展字典。

如果某个词被拆开了,不希望拆开,需要自己加到分词器的词典中。

例如: 

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。

显示效果如下,显示“三体”变成一个词语。

六、Rest风格。

1、Rest风格概述。

一种软件架构风格,提供了一组设计原则和约束条件。不是一个标准。基于这个风格设计的软件可以更简洁,更有层次,易于实现缓存等机制。主要用于客户端和服务器交互类的程序。

2、elasticsearch基本Rest命令。 

|
方法Method
|
地址url
|
描述 |
|
PUT
|
索引名称/类型名称/文档id
|
创建文档,指定文档id。 |
|
POST
|
索引名称/类型名称
|
创建文档,随机文档id。 |
|
POST
|
索引名称/类型名称/文档id/_update
|
修改文档。 |
|
POST
|
索引名称/类型名称/_search
|
查询所有数据。 |
|
DELETE
|
索引名称/类型名称/文档id
|
删除文档。 |
|
GET
|
索引名称/类型名称/文档id
|
通过文档id查询文档。 |

七、关于索引的基本操作。

1、创建一个索引。

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
}

2、Elasticsearch的常用field字段类型。

字符串类型:text、keyword。

数值类型:long、integer、short、byte、double、float、half、float、scaled、float。

日期类型:date。

布尔值类型:boolean。

二进制类型:binary。

3、手动指定field字段的类型。

例如:

PUT /test2
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "age": {
        "type": "long"
      },
      "birthday": {
        "type": "date"
      }
    }
  }
}

查看索引具体信息。

例如:

GET /test1

4、查看默认信息,ES自动默认配置字段类型。

ES 8.0会弃用类型名称。类型名称默认为_doc。

如果创建文档时,没有指定文档字段类型,ES会默认配置字段类型。

例如: 

PUT /test3/_doc/1
{
  "name": "新新1",
  "age": 18,
  "birth": "2021-10-31"
}

查看记录。

GET /test3/_doc/1

查看索引信息。

GET /test3

5、查看ES信息。

使用_cat查看ES信息。

查看ES健康状况。

GET /_cat/health

查看ES索引。

GET /_cat/indice

6、修改索引。

使用PUT方式覆盖数据,覆盖时需要全部字段,否则会丢失字段数据,会生成一个新的文档对象。

PUT /test3/_doc/1
{
  "name": "新新2",
  "age": 18,
  "birth": "2021-10-31"
}

使用POST方式修改索引,可以指定修改某个字段,POST时带_update。

POST /test3/_doc/1/_update
{
  "doc": {
    "name": "新新3"
  }
}

7、删除索引。

使用DELETE命令实现删除。

删除索引。

DELETE /test1

删除document文档,删除记录。

DELETE /test3/_doc/1

八、关于文档的基本操作。

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": ["交友", "旅游", "暖男"]
}

 2、使用GET查询数据,获取数据。 

GET /corp/user/1

 3、更新数据。

使用PUT方式覆盖修改数据。

例如: 

PUT /corp/user/3
{
  "name": "王五",
  "age": 18,
  "desc": "我去年买了个表,去年买了个表,年买了个表,买了个表,了个表,个表,表。",
  "tags": ["靓女", "旅游", "唱歌"]
}

使用POST方式修改数据,推荐的方式。需要带_update。

例如:

POST /corp/user/3/_update
{
  "doc": {
      "name": "刘六"
  }
}

4、简单搜索数据。

(1)简单搜索。

例如:

查询某一条记录,某一个document文档。

GET /corp/user/3

查询所有记录。

GET /corp/user/_search

根据某个字段查询。

GET /corp/user/_search?q=name:张

根据某个字段查询。 

GET /corp/user/_search?q=name:李四

 5、复杂搜索数据。

(1)根据某个字段查询。

例如: 

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分数,符合搜索结果的程度,匹配度。

(2)指定字段查询。

查询返回某几个字段,结果过滤。

例如: 

GET /corp/user/_search
{
  "query": {
    "match": {
      "name": "张三"
    }
  },
  "_source": ["name", "desc"]
}

 (3)查询排序。

使用sort排序,desc降序,asc升序。

GET /corp/user/_search
{
  "query": {
    "match": {
      "name": "张三"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}

 (4)分页查询。

from从第几个数据开始查询,数据下标从0开始。size每页显示几条记录,返回多少条数据。

GET /corp/user/_search
{
  "query": {
    "match": {
      "name": "张三"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ],
  "from": 0,
  "size": 1
}

(5)布尔值查询。

  • 多条件布尔值查询。

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
          }
        }
      ]
    }
  }
}

(6)过滤器filter查询数据。

查询符合某个区间的记录。

gt:大于。

lt:小于。

gte:大于等于。

lte:小于等于。

例如:

GET /corp/user/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "张三"
          }
        }
      ],
      "filter": [
        {
          "range": {
            "age": {
              "gt": 10,
              "lt": 20
            }
          }
        }
      ]
    }
  }
}

(7)匹配多个条件查询。

多个条件使用空格隔开,只要满足其中一个条件就可以被查出,可以通过分值作判断。

GET /corp/user/_search
{
  "query": {
    "match": {
      "tags": "女 唱歌"
    }
  }
}

GET /corp/user/_search
{
  "query": {
    "match": {
      "tags": "男 技术"
    }
  }
}

(8)精确查询。

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"
    }
  }
}

(9)多个值匹配精确查询。

例如:

添加两条数据。 

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"
          }
        }
      ]
    }
  }
}

(10)高亮查询。

  • 使用默认高亮标签。

搜索相关的结果可以高亮显示,默认使用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": {}
    }
  }
}

相关文章

微信公众号

最新文章

更多