利用Kibana学习全文检索工具elasticsearch

elasticsearch的基本概念

cluster整个elasticsear----ch 默认就是集群状态,整个集群是一份完整、互备的数据。
node集群中的一个节点,一般只一个进程就是一个node
Shard分片,即使是一个节点中的数据也会通过hash算法,分成多个片存放,默认是5片。
Index相当于rdbms的database, 对于用户来说是一个逻辑数据库,虽然物理上会被分多个shard存放,也可能存放在多个node中。
Type类似于rdbms的table,但是与其说像table,其实更像面向对象中的class , 同一Json的格式的数据集合。
Document类似于rdbms的 row、面向对象里的object
Field相当于字段、属性

利用kibana学习 elasticsearch restful api (DSL)

1.es中保存的数据结构

public class  Movie {
	 String id;
     String name;
     Double doubanScore;
     List<Actor> actorList;
}

public class Actor{
String id;
String name;
}

这两个对象如果放在关系型数据库保存,会被拆成2张表,但是elasticsearch是用一个json来表示一个document。
所以它保存到es中应该是:

{
  “id”:1,
  “name”:”operation red sea”,
  “doubanScore”:8.5,
  “actorList”:[  
		{“id”:1,”name”:”zhangyi”},
		{“id”:2,”name”:”haiqing”},
		{“id”:3,”name”:”zhanghanyu”}
	]
}

2.对数据的操作

2.1 查看es中有哪些索引

GET /_cat/indices?v

在这里插入图片描述
es 中会默认存在一个名为.kibana的索引
表头的含义

healthgreen(集群完整) yellow(单点正常、集群不完整) red(单点不正常)
status是否能使用
index索引名
uuid索引统一编号
pri主节点几个
rep从节点几个
docs.count文档数
docs.deleted文档被删了多少
store.size整体占空间大小
pri.store.size主节点占
2.2 增加一个索引

PUT /movie_index

在这里插入图片描述

2.3 删除一个索引
  ES 是不删除也不修改任何数据 ,伪删除更新当前index的版本。

DELETE /movie_index

在这里插入图片描述

2.4 新增文档

格式 PUT /index/type/id

例:(如果之前没建过index或者type,es 会自动创建。)

PUT /movie_index/movie/1
{ "id":1,
  "name":"operation red sea",
  "doubanScore":8.5,
  "actorList":[  
		{"id":1,"name":"zhang yi"},
		{"id":2,"name":"hai qing"},
		{"id":3,"name":"zhang han yu"}
	]
}

PUT /movie_index/movie/2
{
  "id":2,
  "name":"operation meigong river",
  "doubanScore":8.0,
  "actorList":[  
		{"id":3,"name":"zhang han yu"}
	]
}

PUT /movie_index/movie/3
{
  "id":3,
  "name":"incident red sea",
  "doubanScore":5.0,
  "actorList":[  
		{"id":4,"name":"liu de hua"}
	]
}

在这里插入图片描述

2.5 直接用id查找

GET movie_index/movie/1

在这里插入图片描述

2.6 修改—整体替换

和新增没有区别

PUT /movie_index/movie/3
{
  "id":"3",
  "name":"incident red sea",
  "doubanScore":"5.0",
  "actorList":[  
		{"id":"1","name":"zhang guo li"}
	]
}
2.7 修改—某个字段 更新es商品中的排名
POST movie_index/movie/3/_update
{ 
  "doc": {
    "doubanScore":"7.0"
  } 
}

在这里插入图片描述

2.8 删除一个document

DELETE movie_index/movie/3

在这里插入图片描述

2.9 搜索type全部数据

GET movie_index/movie/_search

结果

{
  "took": 2,    //耗费时间 毫秒
  "timed_out": false, //是否超时
  "_shards": {
    "total": 5,   //发送给全部5个分片
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 3,  //命中3条数据
    "max_score": 1,   //最大评分
    "hits": [  // 结果
      {
        "_index": "movie_index",
        "_type": "movie",
        "_id": 2,
        "_score": 1,
        "_source": {
          "id": "2",
          "name": "operation meigong river",
          "doubanScore": 8.0,
          "actorList": [
            {
              "id": "1",
              "name": "zhang han yu"
            }
          ]
        }
          。。。。。。。。
          。。。。。。。。
      }

在这里插入图片描述

2.10 按条件查询(全部)
GET movie_index/movie/_search
{
  "query":{
    "match_all": {}
  }
}

在这里插入图片描述

2.11 按分词查询
GET movie_index/movie/_search
{
  "query":{
    "match": {"name":"red"}
  }
}

注意结果的评分
在这里插入图片描述

2.12 按分词子属性查询
GET movie_index/movie/_search
{
  "query":{
    "match": {"actorList.name":"zhang"}
  }
}

在这里插入图片描述

2.13 match phrase 按词组查询
GET movie_index/movie/_search
{
    "query":{
      "match_phrase": {"name":"operation red"}
    }
}

按短语查询,不再利用分词技术,直接用短语在原始数据中匹配
在这里插入图片描述

2.14 fuzzy查询
GET movie_index/movie/_search
{
    "query":{
      "fuzzy": {"name":"rad"}
    }
}

校正匹配分词,当一个单词都无法准确匹配,es通过一种算法对非常接近的单词也给与一定的评分,能够查询出来,但是消耗更多的性能。
在这里插入图片描述

2.15 查询后过滤
GET movie_index/movie/_search
{
    "query":{
      "match": {"name":"red"}
    },
    "post_filter":{
      "term": {
        "actorList.id": 3
      }
    }
}

在这里插入图片描述

2.16 查询前过滤(推荐)

其实准确来说,ES中的查询操作分为2种:查询(query)和过滤(filter)。查询即是之前提到的query查询,它(查询)默认会计算每个返回文档的得分,然后根据得分排序。而过滤(filter)只会筛选出符合的文档,并不计算得分,且它可以缓存文档。所以,单从性能考虑,过滤比查询更快。
换句话说,过滤适合在大范围筛选数据,而查询则适合精确匹配数据。一般应用时,应先使用过滤操作过滤数据,然后使用查询匹配数据。

GET movie_index/movie/_search 
{ 
    "query":{
        "bool":{
          "filter":[ {"term": {  "actorList.id": "1"  }},
                     {"term": {  "actorList.id": "3"  }}
           ], 
           "must":{"match":{"name":"red"}}
         }
    } 
}

term、terms过滤
term、terms的含义与查询时一致。term用于精确匹配、terms用于多词条匹配。不过既然过滤器适用于大氛围过滤,term、terms在过滤中使用意义不大。在项目中建议使用term。
Term: where id = ?
Terms: where id in ()
# select * from skuInfo where id=?
# select * from skuInfo where id in ()
在这里插入图片描述

2.17 过滤–按范围过滤
GET movie_index/movie/_search
{
   "query": {
     "bool": {
       "filter": {
         "range": {
            "doubanScore": {"gte": 8}
         }
       }
     }
   }
}

关于范围操作符:跟html标签中的转义字符一样!

gt 大于 lt 小于 gte 大于等于 lte 小于等于

在这里插入图片描述

2.18 排序
GET movie_index/movie/_search
{
  "query":{
    "match": {"name":"red sea"}
  }
  , "sort": [
    {
      "doubanScore": {
        "order": "desc"
      }
    }
  ]
}

在这里插入图片描述

2.19 分页查询
GET movie_index/movie/_search
{
  "query": { 
  	"match_all": {} 
  },
  //第几条开始查询!
  "from": 1,
  "size": 1
}

在这里插入图片描述

2.20 指定查询的字段
GET movie_index/movie/_search
{
  "query": { 
  	"match_all": {} 
  },
  "_source": ["name", "doubanScore"]
}

在这里插入图片描述

2.21 高亮
GET movie_index/movie/_search
{
    "query":{
      "match": {"name":"red sea"}
    },
    "highlight": {
      "fields": {"name":{} }
    }
    
}

在这里插入图片描述
修改自定义高亮标签

GET movie_index/movie/_search
{
    "query":{
      "match": {"name":"red sea"}
    },
    "highlight": {
      "post_tags": ["</span>"],
      "pre_tags": ["<span>"], 
      "fields": {"name":{} }
    }
}

在这里插入图片描述

2.22 聚合

取出每个演员共参演了多少部电影 – sql : group by

GET movie_index/movie/_search
{ 
  "aggs": {
    "groupby_actor": {
      "terms": {
        "field": "actorList.name.keyword"  
      }
    } 
  }
}

在这里插入图片描述
每个演员参演电影的平均分是多少,并按评分排序

GET movie_index/movie/_search
{ 
  "aggs": {
    "groupby_actor_id": {
      "terms": {
        "field": "actorList.name.keyword" ,
        "order": {
          "avg_score": "desc"
          }
      },
      "aggs": {
        "avg_score":{
          "avg": {
            "field": "doubanScore" 
          }
        }
       }
    } 
  }
}

在这里插入图片描述

3 关于mapping

之前说type可以理解为table,那每个字段的数据类型是如何定义的呢
查看mapping

GET movie_index/_mapping/movie
在这里插入图片描述

实际上每个type中的字段是什么数据类型,由mapping定义。但是如果没有设定mapping系统会自动,根据一条数据的格式来推断出应该的数据格式。

true/false → boolean
1020 → long
20.1 → double,float
“2018-02-01” → date
“hello world” → text + keyword

默认只有text会进行分词,keyword是不会分词的字符串。mapping除了自动定义,还可以手动定义,但是只能对新加的、没有数据的字段进行定义。一旦有了数据就无法再做修改了。

注意:虽然每个Field的数据放在不同的type下,但是同一个名字的Field在一个index下只能有一种mapping定义。

4 中文分词

elasticsearch本身自带的中文分词,就是单纯把中文一个字一个字的分开,根本没有词汇的概念。但是实际应用中,用户都是以词汇为条件,进行查询匹配的,如果能够把文章以词汇为单位切分开,那么与用户的查询条件能够更贴切的匹配上,查询速度也更加快速。
分词器下载网址:https://github.com/medcl/elasticsearch-analysis-ik

4.1 安装

1.下载好的zip包,请放到 /usr/share/elasticsearch/plugins/ 下解压
[root@localhost plugins]# unzip elasticsearch-analysis-ik-5.6.4.zip

2.将压缩包文件删除!否则启动失败!

3.然后重启es
[root@localhost plugins]# service elasticsearch restart

4.2 测试使用

使用默认

GET movie_index/_analyze
{  
  "text": "我是中国人"
}
请观察结果

在这里插入图片描述
使用分词器

GET movie_index/_analyze
{  "analyzer": "ik_smart", 
  "text": "我是中国人"
}
请观察结果

在这里插入图片描述另外一个分词器 ik_max_word

GET movie_index/_analyze
{  "analyzer": "ik_max_word", 
  "text": "我是中国人"
}

请观察结果
在这里插入图片描述
能够看出不同的分词器,分词有明显的区别,所以以后定义一个type不能再使用默认的mapping了,要手工建立mapping, 因为要选择分词器。

4.3 基于中文分词搭建索引

1、建立mapping

PUT movie_chn
{
  "mappings": {
    "movie":{
      "properties": {
        "id":{
          "type": "long"
        },
        "name":{
          "type": "text"
          , "analyzer": "ik_smart"
        },
        "doubanScore":{
          "type": "double"
        },
        "actorList":{
          "properties": {
            "id":{
              "type":"long"
            },
            "name":{
              "type":"keyword"
            }
          }
        }
      }
    }
  }
}

2.插入数据

PUT /movie_chn/movie/1
{ "id":1,
  "name":"红海行动",
  "doubanScore":8.5,
  "actorList":[  
  		{"id":1,"name":"张译"},
  		{"id":2,"name":"海清"},
  		{"id":3,"name":"张涵予"}
 	]
}

PUT /movie_chn/movie/2
{
  "id":2,
  "name":"湄公河行动",
  "doubanScore":8.0,
  "actorList":[  
		{"id":3,"name":"张涵予"}
	]
}

PUT /movie_chn/movie/3
{
  "id":3,
  "name":"红海事件",
  "doubanScore":5.0,
  "actorList":[  
		{"id":4,"name":"张国立"}
	]
}

3.查询测试

GET /movie_chn/movie/_search
{
  "query": {
    "match": {
      "name": "红海战役"
    }
  }
}

GET /movie_chn/movie/_search
{
  "query": {
    "term": {
      "actorList.name": "张译"
    }
  }
}
4.4 自定义词库
	什么时候使用?
	当词库满足不了你的需要,可以使用自定义词库!

1.修改/usr/share/elasticsearch/plugins/ik/config/中的IKAnalyzer.cfg.xml

<?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"></entry>
         <!--用户可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords"></entry>
        <!--用户可以在这里配置远程扩展字典 -->
         <entry key="remote_ext_dict">http://192.168.xx.xxx/fenci/myword.txt</entry>
        <!--用户可以在这里配置远程扩展停止词字典-->
        <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

2.按照标红的路径利用nginx发布静态资源
在nginx.conf中配置

  server {
        listen  80;
        server_name  192.168.xx.xxx;
        location /fenci/ {
           root es;
    }
  }

3.并且在/usr/local/nginx/下建/es/fenci/目录,目录下加myword.txt
在myword.txt中编写关键词,每一行代表一个词。

4.然后重启es服务器,重启nginx。在kibana中测试分词效果

5.配置完成分词之后,要重启es .
若分词失败:看日志 cd /var/log/elasticsearch/ vim my-es.log
更新完成后,es只会对新增的数据用新词分词。历史数据是不会重新分词的。
如果想要历史数据重新分词。需要执行:

POST movies_index_chn/_update_by_query?conflicts=proceed

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值