ES — — elasticsearch初探

Posted 不会敲码的小火鸡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES — — elasticsearch初探相关的知识,希望对你有一定的参考价值。

文章目录

ElasticSearch

一、安装

安装前最好更新一下npm:

npm install -g npm

同时,要求jdk版本 >= 1.8

1、es 安装

我选择的是7.8.1版本,在官网下载自己需要的版本即可:

下载完解压,在bin目录下双击elasticsearch.bat,等待一会,会出现9200端口,即es运行的端口:

我们访问网站,若成功显示如下信息,则表示启动成功:

出现了,“You Know, for Search”。

接下来解决跨域问题:

在es的config目录下,我们编辑elasticsearch.yml:

在最后添加这两句:

http.cors.enabled: true
http.cors.allow-origin: "*"

然后重启es即可。

2、es-head 安装

es-head可以与es建立连接,即时查看es相关信息。

最简单的方法是在chrome的商店里添加elastcisearch-head

与es连接后大概是这样(我之前已经创建了一些索引):

也可以在github上下载对应版本的release,下载解压后按照readme的步骤安装启动即可,默认使用的端口为9100

3、Kibana 安装

Kibana是es配套的可视化工程模块。

注意要选择对应版本的Kibana:

下载解压后,在对应的bin目录下,运行kibana.bat。等待一段时间(有warning不用管),出现5601端口:

我们访问网站,出现如下界面即代表启动成功

右下角的console则是我们学习es主要使用的工具

4、es-analysis-ik 插件安装

es-analysis-ik为es扩展的分词器。

现在es安装目录的plugins目录下新建一个名为 ik 的文件夹,然后在github上下载对应版本的release,将下载的zip解压到我们新建的文件夹内即可。

重启es,可以在终端看到 ik 被启用:

二、使用

1、analysis-ik 的使用和配置

  • 配置

a.ik分词器增加字典条目

在es主目录的plugins/ik/config目录下:

我们可以更改IKAnalyzer.cfg.xml文件来增加自定义字典(这里添加的扩展字典为我们自己创建的文件:truthahn.dic):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict">truthahn.dic</entry>
	 <!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords"></entry>
	<!--用户可以在这里配置远程扩展字典 -->
	<!-- <entry key="remote_ext_dict">words_location</entry> -->
	<!--用户可以在这里配置远程扩展停止词字典-->
	<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
  • 使用

es-analysis-ik分词器有ik_smart(最粗粒度拆分)和ik_max_word(最细粒度拆分)两种模式。示例:

进入Kibana的console界面,

ik_smart:

GET _analyze

  "analyzer": "ik_smart",
  "text": "火鸡科技至臻体验"

ik_max_word:

GET _analyze

  "analyzer": "ik_max_word",
  "text": "火鸡科技至臻体验"

由于我们之前添加的truthahn.dic字典中有“火鸡科技”的条目,若没有添加,ik分词器只会识别出“火鸡”和“科技”。

可以看出,相较于ik_smart,ik_max_word会将字典定义的名词进行进一步的拆分。

2、四大操作:增删改查

  • 前置知识

ES五种method:

ES类型:

  • PUT:

进入Kibana的console界面,创建索引:

PUT /ft1/type1/1

  "name": "火鸡科技",
  "text": "火鸡科技至臻体验"

注意:type类型已经逐渐被丢弃,可以将上面的type1更改为:_doc

PUT /索引名/_doc/文档ID
请求体

在es-head中可以看到索引创建成功并且写入了数据:

具体内容:

同时,我们也可以使用mapping设置索引的一些数据的类型:

PUT /ft4

  "mappings":
    "properties":
      "name":
        "type":"text"
      ,
      "birtyday":
        "type":"date"
      ,
      "age":
        "type": "long"
      
    
  

  • DELETE:

删除索引

DELETE ft2
  • POST:

更新索引:

POST /ft1/_update/1/

  "doc":
    "name":"火鸡PLUS+"
  

可以看到,更新时索引ft1的_version会递增,同时result返回的也是updated

  • GET:

获取索引规则信息

GET ft1

另外,可以用GET _cat/获取es的其他信息:

GET _cat/health
GET _cat/master
GET _cat/aliases
GET _cat/count
GET _cat/indices

3、简单搜索

我们先创建一系列索引:

PUT /truthahn/_doc/1

  "title":"荷塘月色",
  "author":"朱自清",
  "text":"这几天心里颇不宁静。今晚在院子里坐着乘凉,忽然想起日日走过的荷塘,在这满月的光里,总该另有一番样子吧。月亮渐渐地升高了,墙外马路上孩子们的欢笑,已经听不见了;妻在屋里拍着闰儿,迷迷糊糊地哼着眠歌。我悄悄地披了大衫,带上门出去。沿着荷塘,是一条曲折的小煤屑路。这是一条幽僻的路;白天也少人走,夜晚更加寂寞。荷塘四面,长着许多树,蓊蓊郁郁的。路的一旁,是些杨柳,和一些不知道名字的树。没有月光的晚上,这路上阴森森的,有些怕人。今晚却很好,虽然月光也还是淡淡的。"


PUT /truthahn/_doc/2

  "title":"背影",
  "author":"朱自清",
  "text":"我与父亲不相见已二年余了,我最不能忘记的是他的背影。那年冬天,祖母死了,父亲的差使也交卸了,正是祸不单行的日子。我从北京到徐州,打算跟着父亲奔丧回家。到徐州见着父亲,看见满院狼藉的东西,又想起祖母,不禁簌簌地流下眼泪。父亲说,“事已如此,不必难过,好在天无绝人之路!”回家变卖典质,父亲还了亏空;又借钱办了丧事。这些日子,家中光景很是惨淡,一半为了丧事,一半为了父亲赋闲。丧事完毕,父亲要到南京谋事,我也要回北京念书,我们便同行。"


PUT /truthahn/_doc/3

  "title":"曲院风荷",
  "author":"陈璨",
  "text":"六月荷花香满湖,红衣绿扇映清波。木兰舟上如花女,采得莲房爱子多。"

然后我们可以开始简单的搜索:

GET /truthahn/_search?q=title:荷塘月色

结果:

发现title中包含关键字“荷”的索引都被查询到了(PS:十分推荐朱良志教授的《曲院风荷》);

如果搜索“月光”,会发现三个索引同时被查询到:

GET /truthahn/_search?q=text:月光

这是因为上述字段text的类型为text(es会自动识别数据的类型),所以es会对数据使用分词器进行分词,只要包含关键字的一部分即可匹配,同时,我们看到返回的结果中有 _score 字段,"_score"的值越高,则数据与关键字的匹配度越高。

而当我们将对应数据的类型更改为keyword时,es会对keyword类型的数据进行完全匹配:

创建新的索引,所有数据的类型都为keyword:

PUT /llama

  "mappings":
    "properties": 
      "title":
        "type":"keyword"
      ,
      "author":
        "type": "keyword"
      ,
      "text":
        "type": "keyword"
      
    
  


PUT /llama/_doc/1

  "title":"荷塘月色",
  "author":"朱自清",
  "text":"这几天心里颇不宁静。今晚在院子里坐着乘凉,忽然想起日日走过的荷塘,在这满月的光里,总该另有一番样子吧。月亮渐渐地升高了,墙外马路上孩子们的欢笑,已经听不见了;妻在屋里拍着闰儿,迷迷糊糊地哼着眠歌。我悄悄地披了大衫,带上门出去。沿着荷塘,是一条曲折的小煤屑路。这是一条幽僻的路;白天也少人走,夜晚更加寂寞。荷塘四面,长着许多树,蓊蓊郁郁的。路的一旁,是些杨柳,和一些不知道名字的树。没有月光的晚上,这路上阴森森的,有些怕人。今晚却很好,虽然月光也还是淡淡的。"


PUT /llama/_doc/2

  "title":"背影",
  "author":"朱自清",
  "text":"我与父亲不相见已二年余了,我最不能忘记的是他的背影。那年冬天,祖母死了,父亲的差使也交卸了,正是祸不单行的日子。我从北京到徐州,打算跟着父亲奔丧回家。到徐州见着父亲,看见满院狼藉的东西,又想起祖母,不禁簌簌地流下眼泪。父亲说,“事已如此,不必难过,好在天无绝人之路!”回家变卖典质,父亲还了亏空;又借钱办了丧事。这些日子,家中光景很是惨淡,一半为了丧事,一半为了父亲赋闲。丧事完毕,父亲要到南京谋事,我也要回北京念书,我们便同行。"


PUT /llama/_doc/3

  "title":"曲院风荷",
  "author":"陈璨",
  "text":"六月荷花香满湖,红衣绿扇映清波。木兰舟上如花女,采得莲房爱子多。"

truthahn和llama的索引信息:

当执行

GET /truthahn/_search?q=title:荷塘月色
GET /llama/_search?q=title:荷塘月色

时前者返回结果中value为2,而后者则为1

当执行

GET /truthahn/_search?q=text:荷塘月色
GET /llama/_search?q=text:荷塘月色

时前者返回结果中value为2,而后者则为0

我们也可以通过设置分词器的类型来验证:

keyword类型:

GET _analyze

  "analyzer":"keyword",
  "text":"火鸡科技 至臻体验"

结果:


  "tokens" : [
    
      "token" : "火鸡科技 至臻体验",
      "start_offset" : 0,
      "end_offset" : 9,
      "type" : "word",
      "position" : 0
    
  ]

standard类型:

GET _analyze

  "analyzer":"standard",
  "text":"火鸡科技至臻体验"

结果:


  "tokens" : [
    
      "token" : "火",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<IDEOGRAPHIC>",
      "position" : 0
    ,
    
      "token" : "鸡",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "<IDEOGRAPHIC>",
      "position" : 1
    ,
    
      "token" : "科",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "<IDEOGRAPHIC>",
      "position" : 2
    ,
    
      "token" : "技",
      "start_offset" : 3,
      "end_offset" : 4,
      "type" : "<IDEOGRAPHIC>",
      "position" : 3
    ,
    
      "token" : "至",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "<IDEOGRAPHIC>",
      "position" : 4
    ,
    
      "token" : "臻",
      "start_offset" : 5,
      "end_offset" : 6,
      "type" : "<IDEOGRAPHIC>",
      "position" : 5
    ,
    
      "token" : "体",
      "start_offset" : 6,
      "end_offset" : 7,
      "type" : "<IDEOGRAPHIC>",
      "position" : 6
    ,
    
      "token" : "验",
      "start_offset" : 7,
      "end_offset" : 8,
      "type" : "<IDEOGRAPHIC>",
      "position" : 7
    
  ]

4、复杂搜索

还是使用上面创建的索引truthahn的数据,进行复杂搜索:

  • match
GET /truthahn/_search

  "query": 
    "match": 
      "text": "月光"
    
  ,
  "_source": ["text"]

这里的match与

GET /truthahn/_search?q=月光

的规则类似。都是模糊匹配,会先把查询条件进行分词,然后逐个查询。

不同的是"_source"用来规定返回哪些字段,

"_source": ["text"]

说明只返回text字段,而author和name则不返回

  • term

与match相反,term为完全匹配,要求必须包含全部的term字段:

GET /truthahn/_search

  "query": 
    "term": 
      "text": "月光"
    
  

结果:


  "took" : 0,
  "timed_out" : false,
  "_shards" : 
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  ,
  "hits" : 
    "total" : 
      "value" : 0,
      "relation" : "eq"
    ,
    "max_score" : null,
    "hits" : [ ]
  

这是因为term默认使用标准分词器,这样原文就会被拆分成一个个单字,匹配不到“月光”。如果将条件改为:

"text": "月"

"text": "光"

就可以搜索到了。

  • sort
GET /truthahn/_search

  "query": 
    "match": 
      "text": "月光"
    
  ,
  "_source": ["text"],
  "sort": [
    
      "text.keyword": 
        "order": "asc"
      
    
  ]

添加“sort”规则,sort能够对返回的数据进行排序,此时返回的_score为null。

  • from&size
GET /truthahn/_search

  "query": 
    "match": 
      "text": "月光"
    
  ,
  "_source": ["text"],
  "sort": [
    
      "text.keyword": 
        "order": "asc"
      
    
  ],
  "from":0,
  "size":1

添加from和size规则,这两个规则规定返回结果的范围,可以理解成sql语句中的limit,

"from":0,
"size":1

能够获取返回的第一个结果,就类似于

select ... from ... where ... limit 0,1

  • bool

bool规则有must、must_not、should、boost、filter、mininum_should_match等判断逻辑,可以进行多条件查询:

must类似于and、且:

GET /truthahn/_search

  "query": 
    "bool": 
      "must": [
        
          "match":
            "author":"朱自清"
          
        ,
        
          "match": 
            "text": "赋闲"
          
        
      ]
    
  

should类似于or、或:

GET /truthahn/_search

  "query": 
    "bool": 
      "should": [
        
          "match":
            "author":"朱自清"
          
        ,
        
          "match": 
            "text": "赋闲 变卖"
          
        
      ]
    
  

不知大伙有没有注意到,这里的match里可以用空格分隔查询多个条件,实现多条件查询。同时,虽然是should逻辑,但背影的_scroe为6.10,而荷塘月色只有0.83,说明更加匹配。

  • highlight
GET /truthahn/_search

  "query": 
    "term": 
      "text": "月"
    
  ,
  "highlight": 
    "fields": 
      "title": ,
      "author": ,
      "text": 
    
  

可以看到,满足条件的数据都添加了em标签

结语

好久没发博客了,有些写了一半没写完,就搁置了。这次由于工作需要,系统学习了elasticsearch,狂神讲得很好,收获满满。接下来会开始结合es进行相关前后端交互的开发。

感谢

全文搜索引擎 ElasticSearch 还是 Solr?
B站BV号:BV17a4y1x7zq

以上是关于ES — — elasticsearch初探的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch聚合初探——metric篇

Elasticsearch聚合初探——metric篇

Elasticsearch技术分享

Elasticsearch初探

Elasticsearch初探

elasticsearch terms aggs初探