ElasticSearch从0到1

第1章 ElasticSearch介绍

1.1 什么是搜索

一般指通过某个关键字,检索出和关键字相关的信息,属于模糊查询的一种。

1.2 关系型数据库不适合检索

在这里插入图片描述

1.3 全文检索框架介绍

在这里插入图片描述
静态搜索:数据存进去,不会改变了,比如员工信息。
动态搜索:数据存进去后还会变,比如淘宝的商品信息。

1.4 全文检索依赖倒排索引

全文检索最初的含义指提供一个关键字,在整篇文章中,搜索和关键字匹配的片段。在应用开发中一般指提供一个关键字,在整个数据库中,搜索和关键字匹配的数据。
如果要实现全文检索,必须依赖倒排索引
在这里插入图片描述
正排:匹配标题(搜题目)
所有的搜索都是 “倒排索引”(即:搜内容)

在这里插入图片描述

1.5 什么是ElasticSearch

ElasticSearch,基于Lucene(java编写的一个搜索框架),隐藏复杂性,提供简单易用的RestfulAPI接口、JavaAPI接口(还有其他语言的API接口)。
关于ElasticSearch的一个传说,有一个程序员失业了,陪着自己老婆去英国伦敦学习厨师课程。程序员在失业期间想给老婆写一个菜谱搜索引擎,觉得Lucene实在太复杂了,就开发了一个封装了Lucene的开源项目:Compass。后来程序员找到了工作,是做分布式的高性能项目的,觉得Compass不够,就写了ElasticSearch,让Lucene变成分布式的系统。
ElasticSearch是一个实时分布式搜索和分析引擎。它用于全文搜索、结构化搜索、分析。

1.6 ElasticSearch的适用场景

1)维基百科,类似百度百科,牙膏,牙膏的维基百科,全文检索,高亮,搜索推荐。
2)The Guardian(国外新闻网站),类似搜狐新闻,用户行为日志(点击,浏览,收藏,评论)+ 社交网络数据(对某某新闻的相关看法),数据分析,给到每篇新闻文章的作者,让他知道他的文章的公众反馈(好,坏,热门,垃圾,鄙视,崇拜)。
3)Stack Overflow(国外的程序异常讨论论坛),IT问题,程序的报错,提交上去,有人会跟你讨论和回答,全文检索,搜索相关问题和答案,程序报错了,就会将报错信息粘贴到里面去,搜索有没有对应的答案。
4)GitHub(开源代码管理),搜索上千亿行代码。
5)国内:站内搜索(电商,招聘,门户,等等),IT系统搜索(OA,CRM,ERP,等等),数据分析(ES热门的一个使用场景)。

1.7 ElasticSearch的特点

  • 天然分片
    ES把数据分成多个shard,下图中的P0-P2,多个shard可以组成一份完整的数据,这些shard可以分布在集群中的各个机器节点中。随着数据的不断增加,集群可以增加多个分片,把多个分片放到多个机子上,已达到负载均衡,横向扩展。
    在这里插入图片描述

  • 天然集群
    一台ES实例也可以组成一个集群,方便扩容。在扩容时,只需要在其他节点安装ES,直接启动,新节点会基于配置自动在网段中寻找ES集群,自动申请加入集群。

  • 天然索引
    mysql和其他的数据库,需要手动创建索引。 ES在插入数据后自动创建索引。

  • 近实时
    从写入数据到数据可以被搜索到有一个小延迟(大概1秒)

一点补充
(ES是分布式。数据写入ES时是分布式存储(分片,副本)。
HDFS: 分布式存储。每个文件被切块,每个块有N个副本,分散集群不同DataNode节点上。
Kafka: 一个Topic可以有N个Partition,每个Partition有副本。多个副本也是分散在集群的多个Broker上。

partiton: 分片
block切块: 分片

好处: ①单台集群的存储能力有限,通过分片可以扩展存储能力
每台机器都是500G的磁盘,希望存储 600G的数据。
可以将600G的数据切成小片,分布式存储
②可以提升读写单个数据的IO能力。
不切片,读写只会发生在一台机器。使用一台机器IO
切片,N台机器IO

6.0之前的ES
index: 库
type : 表
一个index可以有多个type。 一个库中,可以存多种类型的表。

6.0的ES
index: 库
type : 表
一个index只能有一个type。 type名字可以随意

7.0的ES
index: 库
type : 表(淡化)
一个index只能有一个type。 type名字是固定的 _doc
在创建index时,使用index时,无需指定type!

8.0的ES
index: 库

1.8 ElasticSearch的核心概念

ElasticSearch与数据库的类比:

关系型数据库(比如Mysql)非关系型数据库(ElasticSearch)
数据库Database索引Index
表Table类型Type(7.0版本Type名称固定且默认为_doc)
数据行Row文档Document(JSON格式)
数据列Column字段Field
约束 Schema映射Mapping

1.9 ElasticSearch存入数据和搜索数据机制

在这里插入图片描述
1)索引对象(blog):存储数据的表结构,任何搜索数据,存放在索引对象上 。
2)映射(mapping):数据如何存放到索引对象上,需要有一个映射配置, 包括:数据类型、是否存储、是否分词等。
3)文档(document):一条数据记录,存在索引对象上。
4)文档类型(type):一个索引对象,存放多种类型数据,数据用文档类型进行标识。

1.10 REST

REST是一种思想,推崇简洁和规范的URL表达。
在这里插入图片描述
在这里插入图片描述

第2章 ElasticSearch安装

2.1 安装包下载

ElasticSearch官网: https://www.elastic.co/cn/downloads/elasticsearch

2.2 ElasticSearch安装

2.2.1 解压安装ElasticSearch

1)解压elasticsearch-7.8.0.tar.gz到/opt/module目录下,并更名
[liujiahao@hadoop102 ~]$ tar -zxvf /opt/software/elasticsearch-7.8.0-linux-x86_64.tar.gz -C /opt/module/

[liujiahao@hadoop102 ~]$ mv /opt/module/elasticsearch-7.8.0/ /opt/module/elasticsearch
2)在/opt/module/elasticsearch路径下创建data文件夹
[liujiahao@hadoop102 elasticsearch]$ mkdir data
3)修改配置文件/opt/module/elasticsearch/config/elasticsearch.yml
[liujiahao@hadoop102 config]$ pwd
/opt/module/elasticsearch/config
[liujiahao@hadoop102 config]$ vi elasticsearch.yml

#-----------------------Cluster-----------------------
cluster.name: myes
#-----------------------Node-----------------------
node.name: node102
#-----------------------Paths-----------------------
path.data: /opt/module/elasticsearch/data
#-----------------------Memory-----------------------
bootstrap.memory_lock: false
#-----------------------Network-----------------------
network.host: hadoop102
#-----------------------Discovery-----------------------
discovery.seed_hosts: [“hadoop102”, “hadoop103”,“hadoop104”]
cluster.initial_master_nodes: [“node102”, “node103”,“node104”]
(1)cluster.name
如果要配置集群需要两个节点上的elasticsearch配置的cluster.name相同,都启动可以自动组成集群,这里如果不改cluster.name则默认是cluster.name=my-application,
(2)nodename随意取但是集群内的各节点不能相同
(3)修改后的每行前面不能有空格,修改后的“:”后面必须有一个空格
分发至hadoop103以及hadoop104,分发之后修改配置文件:
[liujiahao@hadoop102 module]$ xsync elasticsearch/
#在hadoop103机器修改以下信息
node.name: node103
network.host: hadoop103

#在hadoop104机器修改以下信息
node.name: node104
network.host: hadoop104

2.2.2 调整linux内核参数

1)切换到root用户,编辑limits.conf 添加类似如下内容
[root@hadoop102 elasticsearch]# vi /etc/security/limits.conf
添加如下内容:

  • soft nofile 65536
  • hard nofile 131072
  • soft nproc 2048
  • hard nproc 4096
    注意:“*” 不要省略掉。以上操作为增加Linux文件系统中可以同时打开的文件句柄数。
    2)切换到root用户修改配置sysctl.conf
    [root@hadoop102 elasticsearch]# vi /etc/sysctl.conf
    添加下面配置:
    vm.max_map_count=655360
    以上修改的Linux配置需要分发至其他节点
    然后,重新启动Linux,必须重启!!!

2.3 ElasticSearch启动

2.3.1 单点启动

[liujiahao@hadoop102 config]$ /opt/module/elasticsearch/bin/elasticsearch

2.3.2 群起脚本

#!/bin/bash
if(($#!=1))
then
        echo 请输入单个start或stop参数!
        exit
fi


if [ $1 = start ]
then
        cmd="nohup /opt/module/elasticsearch/bin/elasticsearch > /dev/null  2>&1 &"
        elif [ $1 = stop ]
        then
                cmd="ps -ef | grep Elasticsearch | grep -v grep | awk  '{print \$2}' | xargs kill "
else
        echo 请输入单个start或stop参数!
fi

for i in hadoop102 hadoop103 hadoop104
do
        echo "--------------$i-----------------"
        ssh $i $cmd
        sleep 3s
done

2.3.3 验证启动

在这里插入图片描述

2.4 安装Kibana

Kibana是一个用于探索、可视化和分享ES数据的客户端。因此在任一节点安装即可。
将kibana压缩包上传到所安装节点的指定目录:
[liujiahao@hadoop102 ~]$ tar -zxvf /opt/software/kibana-7.8.0-linux-x86_64.tar.gz -C /opt/module/

[liujiahao@hadoop102 ~]$ mv /opt/module/kibana-7.8.0-linux-x86_64/ /opt/module/kibana
修改相关配置,连接Elasticsearch
[liujiahao@hadoop102 kibana]$ vi config/kibana.yml

server.host: “hadoop102”
elasticsearch.hosts: [“http://hadoop102:9200”]
i18n.locale: “zh-CN”

启动Kibana
[liujiahao@hadoop102 kibana]$ bin/kibana
浏览器访问hadoop102:5601

第3章 ElasticSearch基本使用

3.1 数据类型

ES中的数据类型十分丰富,具体可参考:
https://www.elastic.co/guide/en/elasticsearch/painless/7.8/painless-types.html
这里仅仅列出核心数据类型:
字符串型:text(分词)、keyword(不分词)
数值型:long、integer、short、byte、double、float、half_float、scaled_float
日期类型:date
布尔类型:boolean

3.2 集群状态查看

#查看节点状况
GET /_cat/nodes?v

#查看健康状况
GET /_cat/health?v

#查看能查看什么
GET /_cat

#查看所有的index
GET /_cat/indices

3.3 Index操作

3.3.1 新增Index

#手动创建Index 需要在创建index时指定mapping信息
PUT stu
{
“mappings”: {
“properties”: {
“id”: {
“type”: “keyword”
},
“name”: {
“type”: “text”
},
“hobby”: {
“properties”: {
“name”: {
“type”: “text”
},
“years”:{
“type”: “integer”
}
}
}
}
}
}
#自动创建 直接向一个不存在的Index插入数据,在插入数据时,系统根据数据的类型,自动推断mapping,自动创建mapping
POST /index3/_doc/1
{
“name”:“jack”,
“age”: 20
}

3.3.2 查看Index

#查看所有的index
GET /_cat/indices

#查看某个index的信息
GET /_cat/indices/.kibana_1

#查看某个index的元数据信息
GET /index1

#查看某个index的表结构
GET /.kibana_1/_mapping

#查看某个index的别名
GET /.kibana_1/_alias

3.3.3 删除Index

#删除index
DELETE /index1

3.3.4 判断Index是否存在

#判断是否存在index 404 - Not Found代表不存在 ,200代表存在
HEAD /stu1

3.3.5 修改Index

目前仅仅支持向Index添加新的字段映射,如下:
PUT /stu1/_mapping
{
“properties” : {
“sex”:{
“type”:“keyword”
}
}
}
对于已经存在的映射字段,不支持更新映射,更新只能创建新的index进行数据迁移。
PUT stu3
{
“mappings” : {
“properties” : {
“id” : {
“type” : “keyword”
},
“name” : {
“type” : “text”
},
“gender” : {
“type” : “keyword”
}
}
}
}

POST _reindex
{
“source”: {
“index”: “stu1”,
“_source”: [“id”,“name”]
},
“dest”: {
“index”: “stu3”
}
}

3.4 数据操作

3.4.1 查询操作

#全表查询
GET /stu1/_search

#查询单条记录
GET /stu1/_doc/2

3.4.2 新增操作

#明确指定id新增
POST /stu1/_doc/2
{
“id”: “1002”,
“name”:“jack”,
“hobby”:[
{
“name” : “跳”,
“years” : 3
},
{
“name” : “rap”,
“years” : 3
}
]
}

PUT /stu1/_doc/3
{
“id”: “1002”,
“name”:“jack1”,
“hobby”:[
{
“name” : “跳”,
“years” : 3
},
{
“name” : “rap”,
“years” : 3
}
]
}

#随机指定id
POST /stu1/_doc
{
“id”: “1002”,
“name”:“jack”,
“hobby”:[
{
“name” : “跳”,
“years” : 3
},
{
“name” : “rap”,
“years” : 3
}
]
}

3.4.3 修改操作

#全量修改
POST /stu1/_doc/1
{
“id”: “1002”,
“name”:“jack”

}

PUT /stu1/_doc/1
{
“name”:“jack1”

}

#增量修改,只修改指定的列
POST /stu1/_update/2
{
“doc”:{
“hobby”:[
{
“name” : “跳”,
“years” : 5
}
]
}
}

3.4.4 删除操作

#删
DELETE /stu1/_doc/1
3.4.5 判断存在操作
#判断是否存在
HEAD /stu1/_doc/2

3.5 分词操作

3.5.1 默认分词

text(允许分词) keyword(不允许分词)

默认的分词器,用来进行英文分词,按照空格分

GET /_analyze
{
“text”:“I am a teacher!”
}

汉语按照字切分

GET /_analyze
{
“text”:“我是中国人”
}
ES自带的分词器,对中文的分词效果不明显,因此使用IK分词器。

3.5.2 IK分词器安装

[liujiahao@hadoop102 elasticsearch]$ cd plugins/
[liujiahao@hadoop102 plugins]$ mkdir ik
[liujiahao@hadoop102 plugins]$ cd ik
[liujiahao@hadoop102 ik]$ unzip /opt/software/elasticsearch-analysis-ik-7.8.0.zip
分发分词器到所有节点
[liujiahao@hadoop102 plugins]$ xsync ik
重新启动Elasticsearch

3.5.3 IK分词器测试

IK提供了两个分词算法ik_smart 和 ik_max_word。
#ik_smart: 智能分词。切分的所有单词的总字数等于词的总字数,即输入总字数=输出总字数
GET /_analyze
{
“text”:“我是中国人”,
“analyzer”: “ik_smart”
}

#ik_max_word: 最大化分词。 输入总字数 <= 输出总字数
GET /_analyze
{
“text”:“我是中国人”,
“analyzer”: “ik_max_word”
}

#没有NLP(自然语言处理,没有人的情感,听不懂人话)功能
GET /_analyze
{
“text”:“我喜欢洗屁股眼儿”,
“analyzer”: “ik_max_word”
}

3.5.4 扩展词库

[liujiahao@hadoop102 config]$ pwd
/opt/module/elasticsearch/plugins/ik/config
[liujiahao@hadoop102 config]$ vim myword.dic
在文件中添加自己定义的词语,之后保存
[liujiahao@hadoop102 config]$ vim IKAnalyzer.cfg.xml

<?xml version="1.0" encoding="UTF-8"?> IK Analyzer 扩展配置 myword.dic 之后分发刚刚的词库文件和配置文件,并重启ES。

第4章 ElasticSearchDSL查询

4.1 数据准备

4.1.1 创建测试用例表

#建表
PUT /test
{
“mappings” : {
“properties” : {
“empid” : {
“type” : “long”
},
“age” : {
“type” : “long”
},
“balance” : {
“type” : “double”
},
“name” : {
“type” : “text”,
“fields” : {
“keyword” : {
“type” : “keyword”,
“ignore_above” : 256
}
}
},
“gender” : {
“type” : “text”,
“fields” : {
“keyword” : {
“type” : “keyword”,
“ignore_above” : 256
}
}
},
“hobby” : {
“type” : “text”,
“analyzer”:“ik_max_word”,
“fields” : {
“keyword” : {
“type” : “keyword”,
“ignore_above” : 256
}
}
}
}
}
}

4.1.2 向表中批量导入数据

在这里插入图片描述

#导入数据:
POST /test/_bulk
{“index”:{“_id”:“1”}}
{“empid”:1001,“age”:20,“balance”:2000,“name”:“李三”,“gender”:“男”,“hobby”:“吃饭睡觉”}
{“index”:{“_id”:“2”}}
{“empid”:1002,“age”:30,“balance”:2600,“name”:“李小三”,“gender”:“男”,“hobby”:“吃粑粑睡觉”}
{“index”:{“_id”:“3”}}
{“empid”:1003,“age”:35,“balance”:2900,“name”:“张伟”,“gender”:“女”,“hobby”:“吃,睡觉”}
{“index”:{“_id”:“4”}}
{“empid”:1004,“age”:40,“balance”:2600,“name”:“张伟大”,“gender”:“男”,“hobby”:“打篮球睡觉”}
{“index”:{“_id”:“5”}}
{“empid”:1005,“age”:23,“balance”:2900,“name”:“大张伟”,“gender”:“女”,“hobby”:“打乒乓球睡觉”}
{“index”:{“_id”:“6”}}
{“empid”:1006,“age”:26,“balance”:2700,“name”:“张大喂”,“gender”:“男”,“hobby”:“打排球睡觉”}
{“index”:{“_id”:“7”}}
{“empid”:1007,“age”:29,“balance”:3000,“name”:“王五”,“gender”:“女”,“hobby”:“打牌睡觉”}
{“index”:{“_id”:“8”}}
{“empid”:1008,“age”:28,“balance”:3000,“name”:“王武”,“gender”:“男”,“hobby”:“打桥牌”}
{“index”:{“_id”:“9”}}
{“empid”:1009,“age”:32,“balance”:32000,“name”:“王小五”,“gender”:“男”,“hobby”:“喝酒,吃烧烤”}
{“index”:{“_id”:“10”}}
{“empid”:1010,“age”:37,“balance”:3600,“name”:“赵六”,“gender”:“男”,“hobby”:“吃饭喝酒”}
{“index”:{“_id”:“11”}}
{“empid”:1011,“age”:39,“balance”:3500,“name”:“张小燕”,“gender”:“女”,“hobby”:“逛街,购物,买”}
{“index”:{“_id”:“12”}}
{“empid”:1012,“age”:42,“balance”:3500,“name”:“李三”,“gender”:“男”,“hobby”:“逛酒吧,购物”}
{“index”:{“_id”:“13”}}
{“empid”:1013,“age”:42,“balance”:3400,“name”:“李球”,“gender”:“男”,“hobby”:“体育场,购物”}
{“index”:{“_id”:“14”}}
{“empid”:1014,“age”:22,“balance”:3400,“name”:“李健身”,“gender”:“男”,“hobby”:“体育场,购物”}
{“index”:{“_id”:“15”}}
{“empid”:1015,“age”:22,“balance”:3400,“name”:“Nick”,“gender”:“男”,“hobby”:“坐飞机,购物”}

4.2 DSL语法介绍

关键字含义类比SQL
query查询select
bool将多个条件进行组合selext xxx from xxx where age=20 and gender=male
must必须符合=
must_not必须不符合!=
should最好符合,如果满足条件,可以加分
filter过滤条件where
term术语匹配gender=male
match全文检索
fuzzy模糊音匹配
from从哪一条开始查
size查询数据的数量limit x
_source指定查询的字段select 字段
multi_match匹配多个字段中的内容
match_phrase短语匹配,将输入的查询内容整个作为整体进行查询,不切词

4.3 DSL查询练习

GET /test/_search

#第一种: REST   ; GET  /index/_search?参数1=值1&参数2=值2
#全表查询,按照年龄降序排序
#弊端:  url的长度是有限的(256位)
GET /test/_search?q=*&sort=age:desc



#第二种: DSL(特定领域语言)  ;  GET  /index/type/_search
#                               { 参数  }
GET /test/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}

#全表查询,按照年龄降序排序,再按照工资降序排序,只取前5条记录的empid,age,balance
GET /test/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    },
    {
      "balance": {
        "order": "desc"
      }
    }
  ],
  "from": 0,
  "size": 5,
  "_source": ["empid","age","balance"]
}

#搜索hobby含有吃饭睡觉的员工
#用和hobby一致的切词算法,先对搜索的关键词进行切词,将切完后的 吃饭、睡觉到 hobby的倒排索引上去匹配
GET _analyze
{
  "analyzer":"ik_max_word",
  "text": "吃饭睡觉"
}

GET /test/_search
{
  "query": {
    "match": {
      "hobby": "吃饭睡觉"
    }
  }
}


#搜索工资是2000的员工
#只有text类型才能切词
GET /test/_search
{
  "query": {
    "match": {
      "balance": 2000
    }
  }
}

#官方不建议
#match一般都是对text类型进行检索
GET /test/_search
{
  "query": {
    "term": {
      "balance": 2000
    }
  }
}


#搜索hobby是“吃饭睡觉”的员工
GET /test/_search
{
  "query": {
    "match": {
      "hobby.keyword": "吃饭睡觉"
    }
  }
}

GET /test/_search
{
  "query": {
    "match_phrase": {
      "hobby": "吃饭睡觉"
    }
  }
}
#搜索name或hobby中带球的员工
GET /test/_search
{
  "query": {
    "multi_match": {
      "query": "球",
      "fields": ["name","hobby"]
    }
  }
}

#搜索男性中喜欢购物的员工
#在bool中可以写must(必须是),must_not(必须不是),filter(过滤),should(最好是)
GET /test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "gender": {
              "value": "男"
            }
          }
        },
        {
          "match": {
            "hobby": "购物"
          }
        }
      ]
    }
  }
}

#搜索男性中喜欢购物,还不能爱去酒吧的员工
GET /test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "gender": {
              "value": "男"
            }
          }
        },
        {
          "match": {
            "hobby": "购物"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "hobby": "酒吧"
          }
        }
      ]
    }
  }
}
#搜索男性中喜欢购物,还不能爱去酒吧的员工,年龄最好在20-30之间
#should如果匹配,加分
GET /test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "gender": {
              "value": "男"
            }
          }
        },
        {
          "match": {
            "hobby": "购物"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "hobby": "酒吧"
          }
        }
      ],
      "should": [
        {
          "range": {
            "age": {
              "gte": 20,
              "lte": 30
            }
          }
        }
      ]
    }
  }
}

#搜索男性中喜欢购物,还不能爱去酒吧的员工,最好在20-30之间,不要40岁以上的
GET /test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "gender": {
              "value": "男"
            }
          }
        },
        {
          "match": {
            "hobby": "购物"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "hobby": "酒吧"
          }
        }
      ],
      "should": [
        {
          "range": {
            "age": {
              "gte": 20,
              "lte": 30
            }
          }
        }
      ],
      "filter": [
        {
          "range": {
            "age": {
              
              "lte": 40
            }
          }
        }
      ]
    }
  }
}
#搜索Nick
GET /test/_search
{
  "query": {
    "fuzzy": {
      "name": "Dick"
    }
  }
}

第5章 ElasticSearch索引别名

5.1 别名介绍

在这里插入图片描述
索引别名就像一个快捷方式或软连接,可以指向一个或多个索引,也可以给任何一个需要索引名的API来使用。
别名带给我们极大的灵活性,允许我们做下面这些:
1)给多个索引分组
2)给索引的一个子集创建视图
3)在运行的集群中可以无缝的从一个索引切换到另一个索引

5.2 别名作用

5.2.1 给多个索引分组

这儿就类似于hql中的分区表,给每天的数据都加上一个日期格式的别名。
在这里插入图片描述

5.2.2 为子集创建视图

将一部分数据扫描出来作为子集。
作用:避免全表扫描
在这里插入图片描述

5.2.3 索引无缝切换

相当于是改变了别名和代码之间的映射关系。当需求发生改变时,就不需要直接修改源码了,让别名重新指向一个新的代码就好。
在这里插入图片描述

6.聚合练习

GET /test/_search

#第一种: REST   ; GET  /index/_search?参数1=值1&参数2=值2
#全表查询,按照年龄降序排序
#弊端:  url的长度是有限的(256位)
GET /test/_search?q=*&sort=age:desc



#第二种: DSL(特定领域语言)  ;  GET  /index/type/_search
#                               { 参数  }
GET /test/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}

#全表查询,按照年龄降序排序,再按照工资降序排序,只取前5条记录的empid,age,balance
GET /test/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    },
    {
      "balance": {
        "order": "desc"
      }
    }
  ],
  "from": 0,
  "size": 5,
  "_source": ["empid","age","balance"]
}

#搜索hobby含有吃饭睡觉的员工
#用和hobby一致的切词算法,先对搜索的关键词进行切词,将切完后的 吃饭、睡觉到 hobby的倒排索引上去匹配
GET _analyze
{
  "analyzer":"ik_max_word",
  "text": "吃饭睡觉"
}

GET /test/_search
{
  "query": {
    "match": {
      "hobby": "吃饭睡觉"
    }
  }
}


#搜索工资是2000的员工
#只有text类型才能切词
GET /test/_search
{
  "query": {
    "match": {
      "balance": 2000
    }
  }
}

#官方不建议
#match一般都是对text类型进行检索
GET /test/_search
{
  "query": {
    "term": {
      "balance": 2000
    }
  }
}


#搜索hobby是“吃饭睡觉”的员工
GET /test/_search
{
  "query": {
    "match": {
      "hobby.keyword": "吃饭睡觉"
    }
  }
}

GET /test/_search
{
  "query": {
    "match_phrase": {
      "hobby": "吃饭睡觉"
    }
  }
}
#搜索name或hobby中带球的员工
GET /test/_search
{
  "query": {
    "multi_match": {
      "query": "球",
      "fields": ["name","hobby"]
    }
  }
}

#搜索男性中喜欢购物的员工
#在bool中可以写must(必须是),must_not(必须不是),filter(过滤),should(最好是)
GET /test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "gender": {
              "value": "男"
            }
          }
        },
        {
          "match": {
            "hobby": "购物"
          }
        }
      ]
    }
  }
}

#搜索男性中喜欢购物,还不能爱去酒吧的员工
GET /test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "gender": {
              "value": "男"
            }
          }
        },
        {
          "match": {
            "hobby": "购物"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "hobby": "酒吧"
          }
        }
      ]
    }
  }
}
#搜索男性中喜欢购物,还不能爱去酒吧的员工,年龄最好在20-30之间
#should如果匹配,加分
GET /test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "gender": {
              "value": "男"
            }
          }
        },
        {
          "match": {
            "hobby": "购物"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "hobby": "酒吧"
          }
        }
      ],
      "should": [
        {
          "range": {
            "age": {
              "gte": 20,
              "lte": 30
            }
          }
        }
      ]
    }
  }
}

#搜索男性中喜欢购物,还不能爱去酒吧的员工,最好在20-30之间,不要40岁以上的
GET /test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "gender": {
              "value": "男"
            }
          }
        },
        {
          "match": {
            "hobby": "购物"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "hobby": "酒吧"
          }
        }
      ],
      "should": [
        {
          "range": {
            "age": {
              "gte": 20,
              "lte": 30
            }
          }
        }
      ],
      "filter": [
        {
          "range": {
            "age": {
              
              "lte": 40
            }
          }
        }
      ]
    }
  }
}
#搜索Nick
GET /test/_search
{
  "query": {
    "fuzzy": {
      "name": "Dick"
    }
  }
}


#统计男女员工各多少人
# 如果聚合后,聚合列的基数为x,希望取到全部数据,size >= x
#聚合时,如果text类型,无法聚合,建议使用keyword类型
GET /test/_search
{
  "aggs": {
    "gendercount": {
      "terms": {
        "field": "gender.keyword",
        "size": 10
      }
    }
  }
}

#统计喜欢购物的男女员工各多少人
GET /test/_search
{
  "query": {
    "match": {
      "hobby": "购物"
    }
  }, 
  "aggs": {
    "gendercount": {
      "terms": {
        "field": "gender.keyword",
        "size": 10
      }
    }
  }
}


#统计喜欢购物的男女员工各多少人,及这些人总体的平均年龄
GET /test/_search
{
  "query": {
    "match": {
      "hobby": "购物"
    }
  }, 
  "aggs": {
    "gendercount": {
      "terms": {
        "field": "gender.keyword",
        "size": 10
      }
    },
    "avgage":{
      "avg": {
        "field": "age"
      }
    }
  }
}


#统计喜欢购物的男女员工各多少人,及这些人不同性别的平均年龄
GET /test/_search
{
  "query": {
    "match": {
      "hobby": "购物"
    }
  },
  "aggs": {
    "gendercount": {
      "terms": {
        "field": "gender.keyword",
        "size": 10
      },
      "aggs": {
        "avgage": {
          "avg": {
            "field": "age"
          }
        }
      }
    }
  }
}





7.别名练习

#建索引时直接声明
PUT movie_index
{  
  "aliases": {
    "movie1": {},
    "movie2": {}
  }, 
  "mappings": {
      "properties": {
        "id":{
          "type": "long"
        },
        "name":{
          "type": "text",
          "analyzer": "ik_smart"
        }
      }
  }
}

POST /movie1/_doc/1
{
  "name":"《猫和老鼠》"
}

GET /movie2/_search

#为已存在的索引增加别名
POST _aliases
{
  "actions": [
    {
      "add": {
        "index": "movie_index",
        "alias": "movie3"
      }
    }
  ]
}



#查询别名
#查询当前所有的别名
GET /_cat/aliases?v

#查某个index的别名
GET /movie_index/_alias 

#删除别名
POST _aliases
{
  "actions": [
    {
      "remove": {
        "index": "movie_index",
        "alias": "movie3"
      }
    }
  ]
}

#修改别名
POST _aliases
{
  "actions": [
    {
      "remove": {
        "index": "movie_index",
        "alias": "movie2"
      }
    },
    {
      "add": {
        "index": "movie_index",
        "alias": "movie22"
      }
    }
  ]
}

#创建子集
POST _aliases
{
  "actions": [
    {
      "add": {
        "index": "test",
        "alias": "manindex",
        "filter": {
           "term": {
             "gender": "男"
           }
        }
      }
    }
  ]
}

GET /manindex/_search

8.模板操作

#查看模板
#每个模板都有index_patterns属性,这个属性代表如果你要创建的index名称和
#某个模板的index_patterns匹配了,就会使用模板定义的属性(mappings,alises,settings)帮你创建index
GET /_cat/templates?v

#创建模板
PUT _template/template_movie
{
  "index_patterns": ["movie*"],
  "aliases" : { 
    "{index}-query": {},
    "movie-query":{}
  },
  "mappings": { 
      "properties": {
        "id": {
          "type": "keyword"
        },
        "movie_name": {
          "type": "text",
          "analyzer": "ik_smart"
        }
      }
    }
}
#删除模板
DELETE  _template/template_movie

#应用模板
POST /movie220712/_doc/1
{
  "price": 30
}

GET movie220712
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值