Linux安装Elasticsearch(手把手入门教程及下载资源)

这篇具有很好参考价值的文章主要介绍了Linux安装Elasticsearch(手把手入门教程及下载资源)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.安装Elasticsearch

介绍Elasticsearch:

  • 分布式,无需人工搭建集群(solr就需要人为配置,使用Zookeeper作为注册中心)
  • Restful风格,一切API都遵循Rest原则,容易上手
  • 近实时搜索,数据更新在Elasticsearch中几乎是完全同步的

1.下载Linux版本tar包

官网地址
点击进入官网点击去体验
Linux安装Elasticsearch(手把手入门教程及下载资源)
下拉找到该模块点击下载
Linux安装Elasticsearch(手把手入门教程及下载资源)
选择系统类型,点击下载
Linux安装Elasticsearch(手把手入门教程及下载资源)
下载好的安装包,也可以某度下载地址 提取码:9htf
Linux安装Elasticsearch(手把手入门教程及下载资源)
上传文件到linux,需要注意的是root是没办法启用Elasticsearch的,所以我们需要创建一个用户youtwo

useradd 用户名
passwd 用户名 #设置用户名的密码

Linux安装Elasticsearch(手把手入门教程及下载资源)
创建的用户名会在/home下创建一个目录
Linux安装Elasticsearch(手把手入门教程及下载资源)
把我们的安装包上传到youtwo目录下
但是文件是属于root的我们需要更改一下组
Linux安装Elasticsearch(手把手入门教程及下载资源)
通过chown修改

chown user[:group] file…
user 所属用户:group用户组 file需要修改的文件
chown youtwo:youtwo elasticsearch-7.16.1-linux-x86_64.tar.gz

Linux安装Elasticsearch(手把手入门教程及下载资源)
修改文件的权限chmod 755 elasticsearch-7.16.1-linux-x86_64.tar.gz
Linux安装Elasticsearch(手把手入门教程及下载资源)

解压文件tar -zxvf elasticsearch-7.16.1-linux-x86_64.tar.gz
注意:后面出现问题就是因为没有切换用户导致的解压前记得切换用户 su -youtwo
Linux安装Elasticsearch(手把手入门教程及下载资源)
修改文件的名称:mv elasticsearch-7.16.1 elasticsearch
Linux安装Elasticsearch(手把手入门教程及下载资源)

2.配置Elasticsearch

进入config目录
Linux安装Elasticsearch(手把手入门教程及下载资源)
配置vi elasticsearch.yml文件需要把前面的#删除

/home/youtwo/elasticsearch/data #数据目录
/home/youtwo/elasticsearch/logs #日志目录
Linux安装Elasticsearch(手把手入门教程及下载资源)
在往下一点还要把:network.host: 0.0.0.0 ip改成这个
#设置允许所有ip可以连接该elasticsearch
Linux安装Elasticsearch(手把手入门教程及下载资源)
在添加下面参数让elasticsearch-head插件可以访问es
http.cors.enabled: true
http.cors.allow-origin: "*"
Linux安装Elasticsearch(手把手入门教程及下载资源)
不然后面运行会报错:Network is unreachable
wq保存退出
记得创建data目录,因为logs已经有了不需要创建
Linux安装Elasticsearch(手把手入门教程及下载资源)
需要保证linux已经安装好jdk1.8及以上版本
Linux安装Elasticsearch(手把手入门教程及下载资源)

运行elasticsearch服务
进入 bin目录下运行./elasticsearch
Linux安装Elasticsearch(手把手入门教程及下载资源)
运行报错了,由于使用root启动导致的
Linux安装Elasticsearch(手把手入门教程及下载资源)
我们切换到另外一个用户:su - youtwo
Linux安装Elasticsearch(手把手入门教程及下载资源)
又遇到问题提示没有jdk,就运行查看版本存在呀
Linux安装Elasticsearch(手把手入门教程及下载资源)
后面排查我们解压什么的都在root用户下解压地址文件还是属于root,我们创建的用户不能使用
Linux安装Elasticsearch(手把手入门教程及下载资源)

现在改下解压后的权限,切换会root 更改权限:chown -R youtwo:youtwo elasticsearch 使用到-R :把目录下的所有权限都跟着一起修改
Linux安装Elasticsearch(手把手入门教程及下载资源)
切换用户并运行
Linux安装Elasticsearch(手把手入门教程及下载资源)
报这个错误是由于文件
Linux安装Elasticsearch(手把手入门教程及下载资源)

3.运行遇到的问题

切换Root用户解决问题
问题1:max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]我们用的是的用户,不是root,所以文件权限不足修改/etc/security/limits.conf添加下面 内容

* soft nofile 65536

* hard nofile 131072

* soft nproc 4096

* hard nproc 4096

Linux安装Elasticsearch(手把手入门教程及下载资源)
wq保存退出

问题2:max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

vm.max_map_count:限制一个进程可以拥有的VMA(虚拟内存区域)的数量,继续修改配置文件, :vim /etc/sysctl.conf
添加:vm.max_map_count=655360
Linux安装Elasticsearch(手把手入门教程及下载资源)
然后运行:sysctl -p
Linux安装Elasticsearch(手把手入门教程及下载资源)

问题3:the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured

修改elasticsearch.yml配置文件
添加cluster.initial_master_nodes: ["node-1"]Linux安装Elasticsearch(手把手入门教程及下载资源)
wq保存退出

在次重启,切换用户运行
Linux安装Elasticsearch(手把手入门教程及下载资源)
问题4:出现UnknownHostException: geoip.elastic.co

Linux安装Elasticsearch(手把手入门教程及下载资源)
修改elasticsearch.yml配置添加ingest.geoip.downloader.enabled: false
Linux安装Elasticsearch(手把手入门教程及下载资源)
在运行就没有出现报错信息
Linux安装Elasticsearch(手把手入门教程及下载资源)

4.浏览器访问Elasticsearch

通过Linux的ip:9200访问
Linux安装Elasticsearch(手把手入门教程及下载资源)

二.ik分词器

1.上传并且解压

Elasticsearch和IK的版本使用
Linux安装Elasticsearch(手把手入门教程及下载资源)

分词器点击下载提取码:feq4
把分词器插件上传到plugins下
Linux安装Elasticsearch(手把手入门教程及下载资源)
Linux安装Elasticsearch(手把手入门教程及下载资源)

解压插件
unzip elasticsearch-analysis-ik-7.16.2.zip -d ik-analyzer
解压完成后记得把压缩包删除
Linux安装Elasticsearch(手把手入门教程及下载资源)

2.出现的问题

在运行elasticsearch出现该问题
Linux安装Elasticsearch(手把手入门教程及下载资源)

原因是ik分词器版本不一致
进入分词器插件目录 vi plugin-descriptor.properties修改配置
Linux安装Elasticsearch(手把手入门教程及下载资源)
elasticsearch.version=改成提示错误的版本号(我这是7.16.1)
Linux安装Elasticsearch(手把手入门教程及下载资源)
wq保存退出
运行Elasticsearch可以看出日志已经输出加载ik分词器了,并且也没有运行报错
Linux安装Elasticsearch(手把手入门教程及下载资源)

3.使用kibana控制台测试

POST _analyze
{
  "analyzer": "ik_max_word",
  "text":     "我是中国人,我很骄傲"
}

Linux安装Elasticsearch(手把手入门教程及下载资源)
发送成功后我们得到以下结果(分词的结果)

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "是",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "中国人",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "中国",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "国人",
      "start_offset" : 3,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "我",
      "start_offset" : 6,
      "end_offset" : 7,
      "type" : "CN_CHAR",
      "position" : 5
    },
    {
      "token" : "很",
      "start_offset" : 7,
      "end_offset" : 8,
      "type" : "CN_CHAR",
      "position" : 6
    },
    {
      "token" : "骄傲",
      "start_offset" : 8,
      "end_offset" : 10,
      "type" : "CN_WORD",
      "position" : 7
    }
  ]
}

但是提示了一个错误,大致意思是Elasticsearch内置的安全特性没有被启用,没有身份验证,任何人都可以访问您的集群,测试阶段不影响
Linux安装Elasticsearch(手把手入门教程及下载资源)

4.解决Kibana运行命令提示安全验证

#! Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See
进入Elasticsearch的config包下的 编辑vi elasticsearch.yml
在里面添加一行禁用安全选项xpack.security.enabled: false
Linux安装Elasticsearch(手把手入门教程及下载资源)
wq保存,重启elasticsearch,先把本地运行的Kibana关闭掉等elasticsearch开启成功后在运行Kibana

三.安装Kibana图形界面

1.Kibana用途

Kibana是一个基于node.js的Elasticsearch索引数据统计工具,可以使用Elasticsearch的聚合功能,生成各种图标,还提供了索引数据控制台.
Linux安装Elasticsearch(手把手入门教程及下载资源)
我这边下载windows版本的,直接去官网下载
Linux安装Elasticsearch(手把手入门教程及下载资源)

2.配置Kibana

解压下载好的Kibana安装包在config下配置kibana.yml
Linux安装Elasticsearch(手把手入门教程及下载资源)
修改elasticsearch.hosts
Linux安装Elasticsearch(手把手入门教程及下载资源)
改成这个里面的ip是部署elasticsearch的服务,集群可以配置多个用逗号隔开
Linux安装Elasticsearch(手把手入门教程及下载资源)

3.运行Kibana

不管是Linux或者windows都是需要node.js的依赖
Linux安装Elasticsearch(手把手入门教程及下载资源)
通过浏览器访问http://安装Kibana访问的ip:5601/
Linux安装Elasticsearch(手把手入门教程及下载资源)
找到这个界面
Linux安装Elasticsearch(手把手入门教程及下载资源)
点进去就会进入Kibana的开发工具,我们可以通过这个来创建Elasticsearch的增上改查等操作
Linux安装Elasticsearch(手把手入门教程及下载资源)

四.Elasticsearch常用操作

1基本概念

Elasticsearch也是基于Lucene的全文检索库,本质也是存储数据,很多概念与MySQL类似的。
 
对比关系:
索引(indices)--------------------------------Databases 数据库
类型(type)-------------------------Table 数据表(从7.x开始已经废弃)
文档(Document)----------------Row 行
字段(Field)-------------------Columns 列

详细说明:

概念 说明
索引库(indices) indices是index的复数,代表许多的索引
类型(type) 类型是模拟mysql中的table概念(不过从7.x开始已经废弃)
文档(document) 存入索引库原始的数据。比如每一条商品信息,就是一个文档
字段(field) 文档中的属性
索引库(indices) indices是index的复数,代表许多的索引
映射配置(mappings) 字段的数据类型、属性、是否索引、是否存储等特性
  • 索引集(Indices,index的复数):逻辑上的完整索引 collection1
  • 分片(shard):数据拆分后的各个部分
  • 副本(replica):每个分片的复制

注意:Elasticsearch本身就是分布式的,因此即便你只有一个节点,Elasticsearch默认也会对你的数据进行分片和副本操作,当你向集群添加新数据时,数据也会在新加入的节点中进行平衡。

2.创建索引

Elasticsearch采用Rest风格Api,因此可以使用工具发起http请求
创建索引请求的格式:

  • 请求方式:PUT
  • 请求路径:/索引名称
  • 请求参数:Json格式
{
    "settings": {
        "number_of_shards": 1,
        "number_of_replicas": 0
      }
}

settings:索引库的设置

  • number_of_shards:分片数量(只有一台就填写1,创建索引后就不能更改了)
  • number_of_replicas:副本数量(只有一台就填写0,创建索引后也可以随时更改)

使用ApiPost发送http请求插入索引库
Linux安装Elasticsearch(手把手入门教程及下载资源)

使用Kibana测试
kibana的控制台,可以对http请求进行简化

PUT /itmei
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  }
}

Linux安装Elasticsearch(手把手入门教程及下载资源)

2.2查看索引设置

Get请求可以帮我们查看索引信息,格式

GET /索引库名

Linux安装Elasticsearch(手把手入门教程及下载资源)
可以使用*来查询所有索引库配置

GET *

2.3删除索引

DELETE /索引库名

创建索引库2
Linux安装Elasticsearch(手把手入门教程及下载资源)
访问索引库2的数据
Linux安装Elasticsearch(手把手入门教程及下载资源)
删除索引库2

DELETE /itmei2

Linux安装Elasticsearch(手把手入门教程及下载资源)
查看索引库2已经返回404找不到了
Linux安装Elasticsearch(手把手入门教程及下载资源)

2.4映射配置

2.4.1创建映射字段
  • 请求方式:PUT
PUT /索引库名/_mapping/类型名称
{
  "properties": {
    "字段名": {
      "type": "类型",
      "index": true,
      "store": true,
      "analyzer": "分词器"
    }
  }
}
  • type:类型,可以是text、long、short、date、integer、object等
  • index:是否索引,默认true
  • store:是否仓储,默认false
  • analyzer:分词器,参数这里使用ik_max_word即使用ik分词器

示例
如果Elasricsearch是7.x以下低版本的可以不需要拼接?include_type_name=true因为7.x之后不支持type导致的

PUT itmei/_mapping/goods?include_type_name=true
{
  "properties":{
    "title":{
      "type":"text",
      "analyzer":"ik_max_word"
    },
    "images":{
      "type":"keyword",
      "index":false
    },
    "price":{
      "type":"float"
    }
  }
}

Linux安装Elasticsearch(手把手入门教程及下载资源)
响应结果:

{
  "acknowledged": true
}
2.4.2查看映射关系

语法
GET /索引库名称/_mapping

示例:

GET  /itmei/_mapping

Linux安装Elasticsearch(手把手入门教程及下载资源)
响应代码

{
  "itmei" : {
    "mappings" : {
      "properties" : {
        "images" : {
          "type" : "keyword",
          "index" : false
        },
        "price" : {
          "type" : "float"
        },
        "title" : {
          "type" : "text",
          "analyzer" : "ik_max_word"
        }
      }
    }
  }
}

2.4.3字段属性详解
2.4.3.1.type

Elasticsearch支持的数据类型非常丰富,我们就拿常用的来介绍

  • String类型,又分两种:

    • text:可分词,不可参与聚合
    • keyword:不可分词,数据会作为完整字段进行匹配,可以参与聚合
  • Numerical:数值类型,分两类

    • 基本数据类型:long、interger、short、byte、double、float、half_float
    • 浮点数的高精度类型:scaled_float
      • 需要指定一个精度因子,比如10或100。elasticsearch会把真实值乘以这个因子后存储,取出时再还原。
  • Date:日期类型

    elasticsearch可以对日期格式化为字符串存储,但是建议我们存储为毫秒值,存储为long,节省空间。

2.4.3.2 index

index影响字段的索引情况。

  • true:字段会被索引,则可以用来进行搜索。默认值就是true
  • false:字段不会被索引,不能用来搜索(有些字段我们需要手动设置,因为必须要参与检索,比如商品图片)
2.4.3.3 store

是否将数据进行额外存储。
如果设置store为true,就会在_source以外额外存储一份数据,多余,因此一般我们都会将store设置为false,事实上,store的默认值就是false。

2.5 新增数据

2.5.1随机生成id

通过POST请求,可以向一个已经存在的索引库中添加数据。

语法:

POST /索引库名/类型名
{
    "key":"value",
    "key2":"value2"
}

示例:

POST /itmei/goods
{
  "title":"红米手机",
  "price":"2999",
  "images":"https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg"
}

Linux安装Elasticsearch(手把手入门教程及下载资源)

响应

{
  "_index" : "itmei",
  "_type" : "goods",
  "_id" : "NI5N5n0BFIP5QEoddtDO",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 3
}
2.5.2通过id查询数据

语法:

GET /索引库名/映射类型名名称/插入的id

示例:

GET itmei/goods/NI5N5n0BFIP5QEoddtDO

Linux安装Elasticsearch(手把手入门教程及下载资源)

响应数据

{
  "_index" : "itmei",
  "_type" : "goods",
  "_id" : "NI5N5n0BFIP5QEoddtDO",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 3,
  "found" : true,
  "_source" : {
    "title" : "红米手机",
    "price" : "2999",
    "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg"
  }
}
2.5.2自定义插入id

如果我们想要自己新增的时候指定id可以这样。

语法:

POST /索引库名/类型名/id值
{
    "key":"value",
    "key2":"value2"
}

示例:

POST /itmei/goods/1
{
  "title":"小米米手机",
  "price":"3999",
  "images":"https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg"
}

可以发现已经自定义id成功了
Linux安装Elasticsearch(手把手入门教程及下载资源)

响应

{
  "_index" : "itmei",
  "_type" : "goods",
  "_id" : "NI5N5n0BFIP5QEoddtDO",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 3
}

通过id查询数据
Linux安装Elasticsearch(手把手入门教程及下载资源)

2.5.4 智能判断识别

Elasticsearch非常智能,你不需要给索引库设置任何mapping映射,它也可以根据你输入的数据来判断类型,动态添加数据映射

示例:

POST /itmei/goods/2

我们在用来的基础上多添加了2个映射名称,也成功插入
Linux安装Elasticsearch(手把手入门教程及下载资源)
在查询id信息,可以正常显示
Linux安装Elasticsearch(手把手入门教程及下载资源)
我们在查看下映射字关系

GET  /itmei/_mapping/

Linux安装Elasticsearch(手把手入门教程及下载资源)

响应数据

{
  "itmei" : {
    "mappings" : {
      "properties" : {
        "images" : {
          "type" : "keyword",
          "index" : false
        },
        "price" : {
          "type" : "float"
        },
        "saleable" : {
          "type" : "boolean"
        },
        "stock" : {
          "type" : "long"
        },
        "title" : {
          "type" : "text",
          "analyzer" : "ik_max_word"
        }
      }
    }
  }
}

stock和saleable都被成功映射了。

2.6 修改数据

我们把刚刚的数据进行修改,修改需要指定id

  • 请求方式:PUT
  • id如果不存在,则新增加
  • id如果存在,则修改

修改前面id为2的数据把OPPO手机改华为手机

PUT itmei/goods/2
{
  "title":"华为手机",
  "price":"999",
  "images":"https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
  "stock":10,
  "saleable":true
}

Linux安装Elasticsearch(手把手入门教程及下载资源)
我们现在在插入id是3的数据手机名称把华为改成OPPO重点在与我们现在还没有创建id是3的数据所以运行后是新增操作

PUT itmei/goods/3
{
  "title":"OPPO手机",
  "price":"1999",
  "images":"https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
  "stock":10,
  "saleable":true
}

Linux安装Elasticsearch(手把手入门教程及下载资源)

2.7 删除数据

我们把刚刚的数据进行删除,删除需要指定id

语法

DELETE /索引库名/类型名/id值

示例

DELETE itmei/goods/3

Linux安装Elasticsearch(手把手入门教程及下载资源)

响应数据

{
  "_index" : "itmei",
  "_type" : "goods",
  "_id" : "3",
  "_version" : 8,
  "result" : "deleted",
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 14,
  "_primary_term" : 3
}

3.查询

我们把查询分为多个模块进行展示

  • 基本查询
  • _source过滤
  • 结果过滤
  • 高级查询
  • 排序

3.1基本查询

语法

GET /索引库名/_search
{
    "query":{
        "查询类型":{
            "查询条件":"查询条件值"
        }
    }
}

这里的query代表一个查询对象,里面可以有不同的查询属性

  • 查询类型:
    • 例如:match_allmatchtermrange 等等
  • 查询条件:查询条件会根据类型的不同,写法也有差异,后面在测试
3.3.1 查询所有(match_all)

Linux安装Elasticsearch(手把手入门教程及下载资源)

GET itmei/_search
{
  "query": {
    "match_all": {}
  }
}
  • query:代表查询对象
  • match_all:代表查询所有

响应数据

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "title" : "红米手机",
          "price" : "2999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg"
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "title" : "OPPO手机",
          "price" : "2999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
          "stock" : 20,
          "saleable" : true
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "title" : "华为手机",
          "price" : "3999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
          "stock" : 20,
          "saleable" : false
        }
      }
    ]
  }
}

  • took:查询花费时间,单位是毫秒
  • time_out:是否超时
  • _shards:分片信息
  • hits:搜索结果总览对象
    • total:搜索到的总条数
    • max_score:所有结果中文档得分的最高分
    • hits:搜索结果的文档对象数组,每个元素是一条搜索到的文档信息
      • _index:索引库
      • _type:文档类型
      • _id:文档id
      • _score:文档得分
      • _source:文档的源数据
3.3.2 匹配查询(match)

我们插入一条数据和手机区分开来

PUT /itmei/goods/4
{
    "title":"长虹电视",
    "images":"http://image.leyou.com/12479122.jpg",
    "price":3899.00
}

现在库里面有3个手机1个电视总共4条数据
Linux安装Elasticsearch(手把手入门教程及下载资源)

  • or关系

match类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是or的关系

Linux安装Elasticsearch(手把手入门教程及下载资源)

GET itmei/_search
{
  "query": {
    "match": {
      "title": "小米手机"
    }
  }
}

响应数据

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.8664205,
    "hits" : [
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "1",
        "_score" : 1.8664205,
        "_source" : {
          "title" : "红米手机",
          "price" : "2999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg"
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "2",
        "_score" : 0.77691567,
        "_source" : {
          "title" : "OPPO手机",
          "price" : "2999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
          "stock" : 20,
          "saleable" : true
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "3",
        "_score" : 0.69441146,
        "_source" : {
          "title" : "华为手机",
          "price" : "3999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
          "stock" : 20,
          "saleable" : false
        }
      }
    ]
  }
}

会把小米手机进行分词查询,由于出现的数据里面没有关于电视所以不会查询出来,多个词是之间是or关系

  • and关系
    有些场景需要使用精准查询所以需要使用到and
GET itmei/_search
{
  "query": {
    "match": {
      "title": {
      "query":"长虹电视",
      "operator":"and"
      }  
    }
  }
}

响应数据

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 4.688036,
    "hits" : [
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "4",
        "_score" : 4.688036,
        "_source" : {
          "title" : "长虹电视",
          "images" : "http://image.leyou.com/12479122.jpg",
          "price" : 3899.0
        }
      }
    ]
  }
}

会把长虹电视同时包含才会查询出来

  • orand之间
    如果使用多个词进行匹配operator 操作符参数设置成 and 只会将此文档排除,我们想要处于中间某种结果.
    可以使用match查询支持 minimum_should_match 最小匹配参数,可以指定必须匹配的词项数用来表示一个文档是否相关通常使用百分比来表示分词之间的的匹配度
    Linux安装Elasticsearch(手把手入门教程及下载资源)
GET itmei/_search
{
  "query": {
    "match": {
      "title": {
      "query":"红米电视4A",
      "minimum_should_match":"50%"
      }   
    }
  }
}

这里我们使用了3个词50%就相当于3*50%等于1.5个字只要包含一个多词就可以被匹配到

3.3.3 多字段查询(multi_match)

multi_matchmatch类似,不同的是它可以在多个字段中查询
我们在创建一个数据并且在数据里面添加一个副标题

PUT /itmei/goods/5
{
  "title":"麒麟手机",
  "price":"4999",
  "subtitle":"华为旗下手机"
}

接着我们使用多字段查询

GET itmei/_search
{
  "query": {
    "multi_match": {
      "query":"华为",
      "fields": ["title","subtitle"]
      }
  }
}
  • fields 数组可以存放多个查询字段
    Linux安装Elasticsearch(手把手入门教程及下载资源)

响应结果

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 2.71415,
    "hits" : [
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "3",
        "_score" : 2.71415,
        "_source" : {
          "title" : "华为手机",
          "price" : "3999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
          "stock" : 20,
          "saleable" : false
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "5",
        "_score" : 0.5753642,
        "_source" : {
          "title" : "麒麟手机",
          "price" : "4999",
          "subtitle" : "华为旗下手机"
        }
      }
    ]
  }
}

由于查询的华为只要存在fields多字段里面,查询里面都可以被显示出来

3.3.4 词条匹配(term)

term 查询被用于精确值 匹配,这些精确值可能是数字、时间、布尔或者那些未分词的字符串
Linux安装Elasticsearch(手把手入门教程及下载资源)

GET itmei/_search
{
  "query": {
    "term": {
      "price": 4999
      }
  }
}

响应数据

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.3862942,
    "hits" : [
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "5",
        "_score" : 1.3862942,
        "_source" : {
          "title" : "麒麟手机",
          "price" : "4999",
          "subtitle" : "华为旗下手机"
        }
      }
    ]
  }
}

3.3.5 多词条精确匹配(terms)

terms 查询和 term 查询一样,但它允许你指定多个值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件就会被查询出来
Linux安装Elasticsearch(手把手入门教程及下载资源)

GET itmei/_search
{
  "query": {
    "terms": {
      "price": [3999,4999,5999]
      }
  }
}

terms下查询的字段是用数组存放多个值进行匹配查询

响应数据

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "title" : "华为手机",
          "price" : "3999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
          "stock" : 20,
          "saleable" : false
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "5",
        "_score" : 1.0,
        "_source" : {
          "title" : "麒麟手机",
          "price" : "4999",
          "subtitle" : "华为旗下手机"
        }
      }
    ]
  }
}

3.2查询结果过滤

默认情况下elasticsearch查询匹配到的数据会把_source的所有字段都进行返回,如果我们需要指定返回什么数据就要使用_source进行过滤

3.2.1.直接指定字段

Linux安装Elasticsearch(手把手入门教程及下载资源)

GET itmei/_search
{
  "_source": ["title","price"], 
  "query": {
    "terms": {
      "price": [3999,4999,5999]
      }
  }
}
  • 添加_source值是数组里面存放需要展示的字段

不通过_source指定字段如图:
Linux安装Elasticsearch(手把手入门教程及下载资源)

3.2.2.指定includes和excludes

我们也可以通过:

  • includes:来指定想要显示的字段
  • excludes:来指定不想要显示的字段

二者都是可选的。

GET itmei/_search
{
  "_source": {
    "includes": "title"
  }, 
  "query": {
    "terms": {
      "price": [3999,4999,5999]
      }
  }
}

Linux安装Elasticsearch(手把手入门教程及下载资源)
不显示某个字段

GET itmei/_search
{
  "_source": {
    "excludes": "title"
  }, 
  "query": {
    "terms": {
      "price": [3999,4999,5999]
      }
  }
}

Linux安装Elasticsearch(手把手入门教程及下载资源)

3.3高级查询

3.3.1 布尔组合(bool)

我们在插入一条数据进行测试,在插入一条电视数据

PUT /itmei/goods/6
{
  "title":"红米电视",
  "price":4999
}

我们现在查询一下索引库的所有数据

GET /itmei/_search
{
  "query": {
    "match_all": {}
  }
}

响应数据

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 6,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
          "title" : "长虹电视",
          "images" : "http://image.leyou.com/12479122.jpg",
          "price" : 3899.0
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "5",
        "_score" : 1.0,
        "_source" : {
          "title" : "麒麟手机",
          "price" : "4999",
          "subtitle" : "华为旗下手机"
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "title" : "华为手机",
          "price" : "3999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
          "stock" : 20,
          "saleable" : false
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "title" : "红米手机",
          "price" : "2999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg"
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "title" : "OPPO手机",
          "price" : "1999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
          "stock" : 20,
          "saleable" : true
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "6",
        "_score" : 1.0,
        "_source" : {
          "title" : "红米电视",
          "price" : 4999
        }
      }
    ]
  }
}

bool把各种其它查询通过must(与)、must_not(非)、should(或)的方式进行组合

GET /itmei/_search
{
  "query": {
    "bool": {
      "must": [{"match":{"title":"华为"}}],
      "must_not": [{"match":{"title":"电视"}}],
      "should": [{"match":{"title": "手机"}}]
      
    }
  }
}

响应数据

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 2.2393317,
    "hits" : [
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "1",
        "_score" : 2.2393317,
        "_source" : {
          "title" : "红米手机",
          "price" : "2999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg"
        }
      }
    ]
  }
}

可以看出加了must_nottitle字段的值都会被排除,接着must会与上should的字段进行展他们都是数组格式意味着可以多个字段进行查询如在这里插入代码片

GET /itmei/_search
{
  "query": {
    "bool": {
      "must": [{"match":{"title":"红米"}}],
      "must_not": [{"match":{"title":"电视"}}],
      "should": [{"match":{"title": "手机"}},{"match":{"title": "华为"}}]
      
    }
  }
}

Linux安装Elasticsearch(手把手入门教程及下载资源)

3.3.2 范围查找(range)

range查询找出某个字段指定区间内的数字或者时间

操作符 介绍
gt 大于
gte 大于等于
lt 小于
lte 小于等于

语法

GET  /索引库/_search
{
  "query": {
    "range": {
      "FIELD": {
        "gte": 10,
        "lte": 20
      }
    }
  }
}

FIELD表示查询的字段,这里标识查询字段的大于等于10小于等于20的范围数据

示例:查询price字段的范围区间

GET  /itmei/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 3999,
        "lte": 4999
      }
    }
  }
}

响应数据

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "5",
        "_score" : 1.0,
        "_source" : {
          "title" : "麒麟手机",
          "price" : "4999",
          "subtitle" : "华为旗下手机"
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "title" : "华为手机",
          "price" : "3999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
          "stock" : 20,
          "saleable" : false
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "6",
        "_score" : 1.0,
        "_source" : {
          "title" : "红米电视",
          "price" : 4999
        }
      }
    ]
  }
}

3.3.3 模糊查询(fuzzy)

fuzzy等价于term的 模糊查询,但是查询的词条和索引库里面的词条可以允许偏差,但是偏差不能超过2位

示例

GET  /itmei/_search
{
  "query": {
    "fuzzy": {
      "title": "麒麟"
    }
  }
}

响应数据

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.6360589,
    "hits" : [
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "5",
        "_score" : 1.6360589,
        "_source" : {
          "title" : "麒麟手机",
          "price" : "4999",
          "subtitle" : "华为旗下手机"
        }
      }
    ]
  }
}

可以通过fuzziness属性设置编辑偏差的距离

GET  /itmei/_search
{
  "query": {
    "fuzzy": {
      "title":{
        "value": "麒麟",
        "fuzziness": 1
      }
    }
  }
}

3.4过滤(filter)

条件查询中进行过滤,有查询都会有影响到文档的评分和排名,如果查询结果中进行了过滤,标签不希望影响到过滤的评分结果,那么就不要把过滤条件作为查询条件使用,而是使用filter方式:
对标题进行模糊查询,并且对价格进行做过滤,这样就可以避免查询出来的数据结果是大于等于2000并且小于等于3000的数据
注意:filter中还可以再次进行bool组合条件过滤。

查询语句


GET itmei/_search
{
  "query": {
    "bool": {
      "must": 
        {
          "match": {
            "title": "小米手机"
          }
        },
      "filter": [
        {
          "range": {
            "price": {
              "gte": 2000,
              "lte": 3000
            }
          }
        }
      ]
    }
  }
}

查询结果

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.920312,
    "hits" : [
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "1",
        "_score" : 1.920312,
        "_source" : {
          "title" : "红米手机",
          "price" : "2999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg"
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "2",
        "_score" : 0.62958694,
        "_source" : {
          "title" : "OPPO手机",
          "price" : "2999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
          "stock" : 20,
          "saleable" : true
        }
      }
    ]
  }
}

Linux安装Elasticsearch(手把手入门教程及下载资源)
无查询条件,直接过滤
如果一次查询只有过滤,没有查询条件,不希望进行评分,我们可以使用constant_score取代只有 filter 语句的 bool 查询。在性能上是完全相同的,但对于提高查询简洁性和清晰度有很大帮助。

查询条件

GET itmei/_search
{
  "query": {
    
    "constant_score": {
      "filter": {
        "range": {
          "price": {
            "gt": 2000,
            "lt": 3000
          }
        }
      }
    }
  }
}

查询结果

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "title" : "红米手机",
          "price" : "2999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg"
        }
      },
      {
        "_index" : "itmei",
        "_type" : "goods",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "title" : "OPPO手机",
          "price" : "2999",
          "images" : "https://cdn.cnbj1.fds.api.mi-img.com/product-images/redmik40ultra-k40pro/specs_header.jpg",
          "stock" : 20,
          "saleable" : true
        }
      }
    ]
  }
}

3.4排序

3.4.1 单字段排序

sort 可以让我们按照不同的字段进行排序,并且通过order指定排序的方式

Linux安装Elasticsearch(手把手入门教程及下载资源)

3.4.2聚合查询出现的问题

注意:文本字段没有针对需要每个文档字段数据的操作(如聚合和排序)进行优化,因此这些操作在默认情况下是禁用的,因为这样可能会作用大量的内存所以会提示错误,需要把排序的字段进行添加索引
解决办法
可以看出提示错误的字段是price价格字段添加

PUT /itmei/_mapping?pretty
{
  "properties": {
    "price": { 
      "type": "text",
      "fielddata": true
    }
  }
}

Linux安装Elasticsearch(手把手入门教程及下载资源)
在运行上面的语句就可以正常展示数据了
Linux安装Elasticsearch(手把手入门教程及下载资源)

3.4.3 多字段排序

假定我们想要结合使用 price和 _score(得分) 进行查询,并且匹配的结果首先按照价格排序,然后按照相关性得分排序

查询语句

GET itmei/_search
{
  "query": {
    "bool": {
      "must":{"match":{"title":"小米手机"}},
      "filter": [
        {
          "range": {
            "price": {
              "gt": 2000,
              "lt": 3000
            }
          }
        }
      ]
    }
  },
  "sort":
    {
      "price": {
        "order": "desc"
      },
      "_score":{
        "order":"desc"
        
      }
    }
}

查询结果
Linux安装Elasticsearch(手把手入门教程及下载资源)

4. 聚合aggregations

聚合可以让我们极其方便的实现对数据的统计、分析

  • 什么手机最多人买?
  • 手机每个月的销售情况?
  • 手机的价格平均多少,最高又是多少?
4.1 基本概念

Elasticsearch中的聚合,包含多种类型,最常用的两种,一个叫,一个叫度量
桶的作用:

按照某种方式对数据进行分组,每一组数据在ES中称为一个桶,例如我们根据车品牌划分,可以得到大众桶、本田桶,奥迪桶……或者我们按照年龄段对人进行划分:0-10,10-20,20-30,30-40等

Elasticsearch中提供的划分桶的方式有很多:

  • Date Histogram Aggregation:根据日期阶梯分组,例如给定阶梯为周,会自动每周分为一组
  • Histogram Aggregation:根据数值阶梯分组,与日期类似
  • Terms Aggregation:根据词条内容分组,词条内容完全匹配的为一组
  • Range Aggregation:数值和日期的范围分组,指定开始和结束,然后按段分组
  • . . . . .

度量(metrics)

分组完成以后,我们一般会对组中的数据进行聚合运算,例如求平均值、最大、最小、求和等,这些在ES中称为度量

比较常用的一些度量聚合方式:

  • Avg Aggregation:求平均值
  • Max Aggregation:求最大值
  • Min Aggregation:求最小值
  • Percentiles Aggregation:求百分比
  • Stats Aggregation:同时返回avg、max、min、sum、count等
  • Sum Aggregation:求和
  • Top hits Aggregation:求前几
  • Value Count Aggregation:求总数
  • ……
4.2 导入数据测试

创建索引:

PUT /cars
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  },
  "mappings": {
    "properties": {
      "color": {
        "type": "keyword"
      },
      "make": {
        "type": "keyword"
      }
    }
  }
}

Linux安装Elasticsearch(手把手入门教程及下载资源)
注意:在ES中,需要进行聚合、排序、过滤的字段其处理方式比较特殊,因此不能被分词。这里我们将colormake这两个文字类型的字段设置为keyword类型,这个类型不会被分词,将来就可以参与聚合

导入数据

POST /cars/_bulk
{ "index": {}}
{ "price" : 10000, "color" : "red", "make" : "honda", "sold" : "2014-10-28" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 30000, "color" : "green", "make" : "ford", "sold" : "2014-05-18" }
{ "index": {}}
{ "price" : 15000, "color" : "blue", "make" : "toyota", "sold" : "2014-07-02" }
{ "index": {}}
{ "price" : 12000, "color" : "green", "make" : "toyota", "sold" : "2014-08-19" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 80000, "color" : "red", "make" : "bmw", "sold" : "2014-01-01" }
{ "index": {}}
{ "price" : 25000, "color" : "blue", "make" : "ford", "sold" : "2014-02-12" }
4. 3聚合为桶

首先,我们按照 汽车的颜色color来划分

查询请求

GET /cars/_search
{
  "size": 0,
  "aggs": {
    "popular_colors": {
      "terms": {
        "field": "color"
      }
    }
  }
}

解析:

  • size: 查询条数,这里设置为0,因为我们不关心搜索到的数据,只关心聚合结果,提高效率
  • aggs:声明这是一个聚合查询,是aggregations的缩写
    • popular_colors:给这次聚合起一个名字,任意
      • terms:划分桶的方式,这里是根据词条划分
        • field:划分桶的字段

Linux安装Elasticsearch(手把手入门教程及下载资源)

查询结果

{
  "took" : 896,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 8,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "popular_colors" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "red",
          "doc_count" : 4
        },
        {
          "key" : "blue",
          "doc_count" : 2
        },
        {
          "key" : "green",
          "doc_count" : 2
        }
      ]
    }
  }
}

  • hits:查询结果为空,因为我们设置了size为0
  • aggregations:聚合的结果
  • popular_colors:我们定义的聚合名称
  • buckets:查找到的桶,每个不同的color字段值都会形成一个桶
    • key:这个桶对应的color字段的值
    • doc_count:这个桶中的文档数量

可以通过这次聚合查询得出卖红色颜色的车销量高!

4.4 桶内度量

前面的例子告诉我们每个桶里面的文档数量,这很有用。 但通常,我们的应用需要提供更复杂的文档度量。 例如,每种颜色汽车的平均价格是多少?

因此,我们需要告诉Elasticsearch使用哪个字段使用何种度量方式进行运算,这些信息要嵌套在内,度量的运算会基于内的文档进行

现在,我们为刚刚的聚合结果添加 求价格平均值的度量

查询请求

GET /cars/_search
{
  "size": 0,
  "aggs": {
    "popular_colors": {
      "terms": {
        "field": "color"
      },
      "aggs": {
        "agg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}
  • aggs:我们在上一个aggs(popular_colors)中添加新的aggs。可见度量也是一个聚合
  • avg_price:聚合的名称
  • avg:度量的类型,这里是求平均值
  • field:度量运算的字段

查询结果

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 8,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "popular_colors" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "red",
          "doc_count" : 4,
          "agg_price" : {
            "value" : 32500.0
          }
        },
        {
          "key" : "blue",
          "doc_count" : 2,
          "agg_price" : {
            "value" : 20000.0
          }
        },
        {
          "key" : "green",
          "doc_count" : 2,
          "agg_price" : {
            "value" : 21000.0
          }
        }
      ]
    }
  }
}

Linux安装Elasticsearch(手把手入门教程及下载资源)

可以看出agg_price 每种颜色车的平均价格

4.5 桶内嵌套桶

刚刚的案例中,我们在桶内嵌套度量运算。事实上不仅可以嵌套运算还可以再嵌套其它桶。也就是说在每个分组中,再分更多组

比如:我们想统计每种颜色的汽车中,分别属于哪个制造商,按照make字段再进行分桶

查询请求

GET /cars/_search
{
  "size": 0,
  "aggs": {
    "popular_colors": {
      "terms": {
        "field": "color"
      },
      "aggs": {
        "agg_price": {
          "avg": {
            "field": "price"
          }
        },
        "maker":{
          "terms": {
            "field": "make"
            
          }
        }
      }
    }
  }
}
  • 原来的color桶和avg计算我们不变
  • maker:在嵌套的aggs下新添一个桶,叫做maker
  • terms:桶的划分类型依然是词条
  • filed:这里根据make字段进行划分

查询结果

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 8,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "popular_colors" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "red",
          "doc_count" : 4,
          "maker" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "honda",
                "doc_count" : 3
              },
              {
                "key" : "bmw",
                "doc_count" : 1
              }
            ]
          },
          "agg_price" : {
            "value" : 32500.0
          }
        },
        {
          "key" : "blue",
          "doc_count" : 2,
          "maker" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "ford",
                "doc_count" : 1
              },
              {
                "key" : "toyota",
                "doc_count" : 1
              }
            ]
          },
          "agg_price" : {
            "value" : 20000.0
          }
        },
        {
          "key" : "green",
          "doc_count" : 2,
          "maker" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "ford",
                "doc_count" : 1
              },
              {
                "key" : "toyota",
                "doc_count" : 1
              }
            ]
          },
          "agg_price" : {
            "value" : 21000.0
          }
        }
      ]
    }
  }
}

  • 我们可以看到,新的聚合maker被嵌套在原来每一个color的桶中。
  • 每个颜色下面都根据 make字段进行了分组
  • 我们能读取到的信息:
    • 红色车共有4辆
    • 红色车的平均售价是 $32,500 美元。
    • 其中3辆是 Honda 本田制造,1辆是 BMW 宝马制造。

Linux安装Elasticsearch(手把手入门教程及下载资源)

4.6.划分桶的其它方式

前面讲了,划分桶的方式有很多,例如:

  • Date Histogram Aggregation:根据日期阶梯分组,例如给定阶梯为周,会自动每周分为一组
  • Histogram Aggregation:根据数值阶梯分组,与日期类似
  • Terms Aggregation:根据词条内容分组,词条内容完全匹配的为一组
  • Range Aggregation:数值和日期的范围分组,指定开始和结束,然后按段分组

刚刚的案例中,我们采用的是Terms Aggregation,即根据词条划分桶。

接下来,我们再学习几个比较实用的:

4.6.1.阶梯分桶Histogram

原理:

histogram是把数值类型的字段,按照一定的阶梯大小进行分组。你需要指定一个阶梯值(interval)来划分阶梯大小。

比如:

价格字段做了阶梯分组,那么就需要设置interal的值为500,那么阶梯就是 0,500,1000,1500,…

上面列出的是每个阶梯的key,也是区间的启点(0-500,500-1000)。

阶梯公式
bucket_key = Math.floor((value - offset) / interval) * interval + offset

value:就是当前数据的值,本例中是450
offset:起始偏移量,默认为0
interval:阶梯间隔,比如500

对汽车价格进行阶梯分组,设置interval为5000:

查询请求

GET /cars/_search
{
  "size": 0,
  "aggs": {
    "price":{
      "histogram": {
        "field": "price",
        "interval": 5000
      }
    }
  }
}

查询结果

{
  "took" : 16,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 8,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "price" : {
      "buckets" : [
        {
          "key" : 10000.0,
          "doc_count" : 2
        },
        {
          "key" : 15000.0,
          "doc_count" : 1
        },
        {
          "key" : 20000.0,
          "doc_count" : 2
        },
        {
          "key" : 25000.0,
          "doc_count" : 1
        },
        {
          "key" : 30000.0,
          "doc_count" : 1
        },
        {
          "key" : 35000.0,
          "doc_count" : 0
        },
        {
          "key" : 40000.0,
          "doc_count" : 0
        },
        {
          "key" : 45000.0,
          "doc_count" : 0
        },
        {
          "key" : 50000.0,
          "doc_count" : 0
        },
        {
          "key" : 55000.0,
          "doc_count" : 0
        },
        {
          "key" : 60000.0,
          "doc_count" : 0
        },
        {
          "key" : 65000.0,
          "doc_count" : 0
        },
        {
          "key" : 70000.0,
          "doc_count" : 0
        },
        {
          "key" : 75000.0,
          "doc_count" : 0
        },
        {
          "key" : 80000.0,
          "doc_count" : 1
        }
      ]
    }
  }
}

你会发现doc_count有很多结果都是为0那么就,显得很多数据是无用的,那么要怎么避免呢?
需要用到参数min_doc_count为1,来约束最少文档数量为1,这样文档数量为0的桶会被过滤

请求参数

GET /cars/_search
{
  "size": 0,
  "aggs": {
    "price":{
      "histogram": {
        "field": "price",
        "interval": 5000,
        "min_doc_count": 1
      }
    }
  }
}

请求结果
Linux安装Elasticsearch(手把手入门教程及下载资源)

4.5.2.范围分桶range

范围分桶与阶梯分桶类似,也是把数字按照阶段进行分组,只不过range方式需要你自己指定每一组的起始和结束大小。

查询请求


GET /cars/_search
{
  "size": 0,
  "aggs": {
    "price_range":{
      "range": {
        "field": "price",
        "ranges": [
          {
            "from": 5000,
            "to": 50000
          }
        ]
      }
     
    }
  }
}

查询结果

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 8,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "price_range" : {
      "buckets" : [
        {
          "key" : "5000.0-50000.0",
          "from" : 5000.0,
          "to" : 50000.0,
          "doc_count" : 7
        }
      ]
    }
  }
}

Linux安装Elasticsearch(手把手入门教程及下载资源)文章来源地址https://www.toymoban.com/news/detail-400691.html

到了这里,关于Linux安装Elasticsearch(手把手入门教程及下载资源)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 手把手教你 在linux上安装kafka

    目录 1. 准备服务器 2. 选一台服务器配置kafka安装包 2.1 下载安装包 2.2 解压安装包 2.3 修改配置文件 3. 分发安装包到其他机器 4. 修改每台机器的broker.id 5. 配置环境变量 6. 启停kafka服务 6.1 启动kafak服务 6.2 停止kafka服务                  1.买几台云服务器 或者 自

    2023年04月19日
    浏览(48)
  • 手把手教你入门Vue,猴子都能看懂的教程

    概述 : 动态构建 用户界面 的 渐进式 框架 动态构建 :虚拟DOM 用户界面 渐进式 作者 特点 声明式 编码、遵循 MVVM 原则 编码简单、体积小 组件化、复用率高、代码维护容易 vue2官网资源 :https://v2.cn.vuejs.org/ 2.1 插值语法 概述 :解析 标签体 内容、可以解析表达式( 可以返

    2024年01月17日
    浏览(25)
  • Linux环境下RabbitMQ的安装(手把手教你安装与配置)

    根据rabbitmq版本要求下载满足要求的erlang RabbitMQ Erlang Version Requirements — RabbitMQ 以我自己的下载版本为例,提供网盘下载链接 链接:https://pan.baidu.com/s/1HkQphzjHp5xNvjN8RZauww?pwd=6666  提取码:6666 登录官网RabbitMQ Erlang Version Requirements — RabbitMQ 下滑至该位置,点击进入   一般不会下

    2024年02月04日
    浏览(29)
  • CentOS7(Linux)详细安装教程(手把手图文详解版)

    目录 一、CentOS镜像的下载(准备工作) 1、官网地址:https://www.centos.org/(官网的下载速度会很慢,不推荐) 2、其他镜像源的下载地址(推荐) 3、选择合适版本的镜像进行下载  二、环境的安装 1、打开我们的虚拟机(VMware Workstation),点击文件进行新建 2、选择典型之后,

    2024年02月08日
    浏览(44)
  • Linux虚拟机的安装与创建【超详细】【手把手教学】

    Linux操作系统于1991年,由芬兰的一个研究生 林纳斯 ● 托瓦兹(Linus Torvalds)开发,免费开源。 特点: 完全免费:源代码 多用户 多任务 良好的用户界面 支持多种平台 设备独立性 丰富的网络功能 完善的数据库和开发平台 安全性 可移植性 你所需要的所有虚拟机文件: 链接

    2024年02月08日
    浏览(37)
  • CentOS7(Linux)详细安装教程(手把手图文详解版)_centos7安装教程

    3、选择合适版本的镜像进行下载 选择合适的存放地址(这里的地址包含中文名称我用起来好像也没出啥问题,如果怕出错的同学可以使用全英文) 1、打开我们的虚拟机(VMware Workstation),点击文件进行新建 2、选择典型之后,下一步 3、选择稍会安装操作系统 4、因为安装的

    2024年04月29日
    浏览(35)
  • 手把手带你在Linux上安装带GPU加速的opencv库(C++版本)

    出现下面类似错误 E: unable to locate libjasper-dev ,运行以下命令. 提示没有 E: unable to locate libjasper-dev 这个包,需要添加数字签名: 检查一下有没有漏装依赖(非常重要,否则后续会失败) 需要出现这面这行提示,说明依赖安装好了 下载源码 在opencv文件夹内新建build文件夹 编译

    2024年04月13日
    浏览(20)
  • 【手把手】ElasticSearch的分词器相关

    不同的分词器对词语的切分也不一样。 分词之前的预处理,过滤无用字符 HTML Strip 自定义字符过滤器my_analyzer,作用是过滤数据中的html标签 可使用 \\\"escaped_tags\\\":[\\\"a\\\"] 设置保留不被过滤的标签 Mapping 通过自定义的过滤器,可以将聊天、留言或者弹幕之类的发言根据需求进行屏蔽

    2024年02月05日
    浏览(27)
  • 【手把手】ElasticSearch的搜索推荐相关

    搜索一般都会要求具有“搜索推荐”或者叫“搜索补全”的功能,即在用户输入搜索的过程中,进行自动补全或者纠错。以此来提高搜索文档的匹配精准度,进而提升用户的搜索体验,这就是Suggest。 term suggester正如其名,只基于tokenizer之后的单个term去匹配建议词,并不会考

    2024年02月07日
    浏览(19)
  • MATLAB :【12】手把手教你在Linux以命令行方式(静默方式/非图形化方式)安装MATLAB(正版)

    碎碎念: (我知道我已经鸽了两个月,但是已经攒了很多的稿子没有发) 大家好,由于实验室的服务器中没有提供MATLAB的计算资源( 事实证明是我不知道QAQ ),在Ubuntu中安装了非图形的MATLAB。 通过参考其他博主的思路,并且利用T大提供的正版资源,中间踩了不少坑,最终

    2024年02月09日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包