前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ElasticSearch快速入门(一)

ElasticSearch快速入门(一)

作者头像
十玖八柒
发布2022-08-01 09:54:28
1.8K0
发布2022-08-01 09:54:28
举报
文章被收录于专栏:ahzoo.cn的博客分享

前言

Elaticsearch,简称为 ES, 是一个开源的高扩展的分布式全文搜索引擎 (这里说到的全文搜索引擎指的是目前广泛应用的主流搜索引擎)。与传统型关系数据库不同,Elaticsearch使用的是倒排索引,它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。

例如百度、谷歌之类的搜索引擎,它们都是根据网页中的关键字生成索引的,当我们在这类搜索引擎输入关键字进行搜索时,它们会根据关键字去匹配索引,然后将索引对应的所有网页返回;除了这类搜索引擎之外,还一些非结构化的数据文本等,对于这些内容的搜索,关系型数据库搜索不是能很好的支持。而且一般传统数据库,全文检索都实现的很鸡肋,因为一般也没人用数据库存文本字段(除了wordpress,之前折腾wordpress时,把数据库删了,文章直接就没了,后面发现wordpress竟然把文章存在数据库里 ==+ )。当进行全文检索时,需要扫描整个表,如果数据量大的话即使对 SQL 的语法优化,也收效甚微。即使建立了索引,后期维护起来也比较麻烦,进行插入和更新操作时都会重新构建索引。 全文搜索引擎的适用场景:

  • 搜索的数据对象是大量的非结构化的文本数据。
  • 文件记录量达到数十万或数百万个甚至更多。
  • 支持大量基于交互式文本的查询。
  • 需求非常灵活的全文搜索查询。
  • 对高度相关的搜索结果的有特殊需求,但是没有可用的关系数据库可以满足。
  • 对不同记录类型、非文本数据操作或安全事务处理的需求相对较少的情况。

下载安装

Elasticsearch 的官方地址,下载完后直接解压;

图片
图片

进入 bin 文件目录,点击 elasticsearch.bat 文件启动 ES 服务

图片
图片

打开地址:http://localhost:9200,测试是否启动成功

图片
图片

RESTful

在SpringMVC中有提到过。

REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就 是 RESTful。Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之 间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务 器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用 服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。 在服务器端,应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体,它 向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每个资源都使用 URI (Universal Resource Identifier) 得到一个唯一的地址。所有资源都共享统一的接口,以便在客 户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如 GET、PUT、POST 和 DELETE。

在 REST 样式的 Web 服务中,每个资源都有一个地址。资源本身都是方法调用的目 标,方法列表对所有资源都是一样的。这些方法都是标准方法,包括 HTTP GET、POST、 PUT、DELETE,还可能包括 HEAD 和 OPTIONS。简单的理解就是,如果想要访问互联 网上的资源,就必须向资源所在的服务器发出请求,请求体中必须包含资源的网络路径,以 及对资源进行的操作(增删改查)。

第三方工具

使用Elasticsearch服务器发请求时必须包含HTTP 标准的方法,而大部分浏览器默认发送的只有 GET 和 POST 请求。所以为了能方便地进行客户端的访问,

我们可以使用Postman 网页调试工具配合使用。

图片
图片

Postman下载安装后,按照提示填写信息,然后随便创建一个team就可以了;

图片
图片

使用Elasticsearch服务器发请求时必须包含HTTP 标准的方法,而大部分浏览器默认发送的只有 GET 和 POST 请求。所以为了能方便地进行客户端的访问,

我们可以使用以下几种工具可配合使用。

  1. Kibana,Elastic官方提供的ES可视化工具
图片
图片
  1. Postman ,功能强大网页调试工具,可用于完成ES各种请求
图片
图片
  1. Chrome的ES插件
图片
图片
  1. elasticsearch-head,界面简陋,但是使用十分方便的ES在线可视化工具

数据格式

Elasticsearch 是面向文档型数据库,一条数据对应的就是一个文档。

与MySQL的类比:

图片
图片

ES 里的 Index 可以看做一个库,而 Types 相当于表,Documents 则相当于表的行。 这里 Types 的概念已经被逐渐弱化,Elasticsearch 6.X 中,一个 index 下已经只能包含一个 type,Elasticsearch 7.X 中, Type 的概念已经被删除了

用 JSON 作为文档序列化的格式,比如一条用户信息:

代码语言:javascript
复制
{
 "name" : "Ahzoo",
 "age" : 18,
 "birthDate": "01/23",
 "about" : "nothing",
 "interests": [ "sports", "music" ]
}

HTTP操作

Postman

索引操作

为了方便演示RESTful风格,这里使用的是Postman进行操作,如果不用RESTful风格,可直接跳到Kibana

打开Postman,按照提示进行初始化设置;

进入Postman界面后,新建一个Collection;

图片
图片
创建索引

相当于关系型数据库中的创建数据库

点击右侧加号;输入一个PUT命令:

代码语言:javascript
复制
PUT http://127.0.0.1:9200/shopping

然后点击Send,可以看到创建成功的提示 返回结果:

代码语言:javascript
复制
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "shopping"
}
图片
图片

重复添加时会报错: 返回结果:

代码语言:javascript
复制
{
  "error" : {
    "root_cause" : [
      {
        "type" : "resource_already_exists_exception",
        "reason" : "index [shopping/oTiQnf9UT--dwgsZ_2wBow] already exists",
        "index_uuid" : "oTiQnf9UT--dwgsZ_2wBow",
        "index" : "shopping"
      }
    ],
    "type" : "resource_already_exists_exception",
    "reason" : "index [shopping/oTiQnf9UT--dwgsZ_2wBow] already exists",
    "index_uuid" : "oTiQnf9UT--dwgsZ_2wBow",
    "index" : "shopping"
  },
  "status" : 400
}
查询索引

输入一个GET命令,来查询所有索引;(cat 表示查看的意思,indices 表示索引,相当于像 MySQL 中的 show tables)

代码语言:javascript
复制
GET http://127.0.0.1:9200/_cat/indices?v

返回结果:

代码语言:javascript
复制
health status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   .geoip_databases                fjfmnkm2RZKMHtGbBQGweg   1   0         41           39     40.1mb         40.1mb
green  open   .kibana_7.15.0_001              mKyI2n3oSaK-U7-BIepohA   1   0         51            5      2.3mb          2.3mb
green  open   .apm-custom-link                4m9W5TxCRJSs8I6GqDepMw   1   0          0            0       208b           208b
green  open   .apm-agent-configuration        731dsjx0TaWdnmGqyKBvQQ   1   0          0            0       208b           208b
green  open   .kibana-event-log-7.15.0-000001 2__Yx8BARWGwOgCarYgezA   1   0          1            0        6kb            6kb
green  open   .kibana_task_manager_7.15.0_001 bWnZfG6aQPyCXa8j23Mimw   1   0         15         3825    540.5kb        540.5kb
yellow open   shopping                        VxYeY2FBS6a8wZxgWEdGtQ   1   1          0            0       208b           208b
图片
图片

查询单个索引

代码语言:javascript
复制
GET http://127.0.0.1:9200/shopping

返回结果:

代码语言:javascript
复制
{
    "shopping": {
        "aliases": {},
        "mappings": {},
        "settings": {
            "index": {
                "routing": {
                    "allocation": {
                        "include": {
                            "_tier_preference": "data_content"
                        }
                    }
                },
                "number_of_shards": "1",
                "provided_name": "shopping",
                "creation_date": "1633513773067",
                "number_of_replicas": "1",
                "uuid": "VxYeY2FBS6a8wZxgWEdGtQ",
                "version": {
                    "created": "7150099"
                }
            }
        }
    }
}
图片
图片
删除索引
代码语言:javascript
复制
DELETE http://127.0.0.1:9200/shopping

返回结果:

代码语言:javascript
复制
{
  "acknowledged" : true
}
图片
图片
文档操作
创建文档

这里的文档就相当于MySQL中的表中的数据

发送一个POST请求,创建文档,文档的格式为JSON:

  • POST

选择POST请求(由于此处没有指定ID为非幂等性操作,所以只能用POST):

简单理解幂等性:多次操作与一次操作的结果相同,即为幂等性操作;反之 此例中由于没有指定ID,所以ID为随机生成,导致多次操作与一次操作的结果不同

代码语言:javascript
复制
POST http://127.0.0.1:9200/shopping/_doc

输入请求体:点击Body,点击raw,格式选择JSON,并在输入框输入请求体(请求完成后记得把请求体删除,否则遇到不需要请求体的命令时会报错)

代码语言:javascript
复制
{
 "title":"HUAWEI Mate 40 Pro",
 "category":"华为手机",
 "images":"https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
 "price":6299
}

然后点击Send发送请求;

返回结果(附解释):

代码语言:javascript
复制
{
    "_index"【索引】: "shopping",
    "_type"【类型-文档】: "_doc",
    "_id"【唯一标识】: "qHRAVXwBGcQwpwap0CcF", //可以类比为 MySQL 中的主键,随机生成
    "_version"【版本】: 1,
    "result"【结果】: "created",//这里的 create 表示创建成功
    "_shards"【分片】: {
        "total"【分片 - 总数】: 2,
        "successful"【分片 - 成功】: 1,
        "failed"【分片 - 失败】: 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}
图片
图片
  • PUT/POST

上面的数据创建后,由于没有指定数据唯一性标识(ID)(也就是主键),默认情况下,ES 服务器会随机生成一个。 如果想要自定义唯一性标识,需要在创建时指定(此时就变成了幂等性操作,因此可以使用POST和PUT两种请求方式):

代码语言:javascript
复制
POST/PUT http://127.0.0.1:9200/shopping/_doc/1

请求体:(请求完成后记得把请求体删除,否则遇到不需要请求体的命令时会报错)

代码语言:javascript
复制
{
 "title":"HUAWEI Mate 40 Pro",
 "category":"华为手机",
 "images":"https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
 "price":6299
}

返回结果:

代码语言:javascript
复制
{
    "_index": "shopping",
    "_type": "_doc",
    "_id": "1", // 可以看到ID为指定的 1
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 1,
    "_primary_term": 1
}
图片
图片
查看文档
  • 通过主键(ID)查询,此处的1为刚才创建的ID
代码语言:javascript
复制
GET http://127.0.0.1:9200/shopping/_doc/1

返回结果:

代码语言:javascript
复制
{

  "_index": "shopping",

  "_type": "_doc",

  "_id": "1",

  "_version": 2,

  "_seq_no": 2,

  "_primary_term": 1,

  "found": **true**,

  "_source": {

​    "title": "HUAWEI Mate 40 Pro",

​    "category": "华为手机",

​    "images": "https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",

​    "price": 6299

  }

}
图片
图片
  • 通过_search查询目标索引全部数据
代码语言:javascript
复制
http://127.0.0.1:9200/shopping/_search
代码语言:javascript
复制
{
    "took": 3,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "shopping",
                "_type": "_doc",
                "_id": "qHRAVXwBGcQwpwap0CcF",
                "_score": 1.0,
                "_source": {
                    "title": "HUAWEI Mate 40 Pro",
                    "category": "华为手机",
                    "images": "https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
                    "price": 6299
                }
            },
            {
                "_index": "shopping",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {
                    "title": "HUAWEI Mate 40 Pro",
                    "category": "华为手机",
                    "images": "https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
                    "price": 6299
                }
            }
        ]
    }
}
图片
图片
修改文档
  • 全量修改
代码语言:javascript
复制
POST/PUT http://127.0.0.1:9200/shopping/_doc/1

请求体:(请求完成后记得把请求体删除,否则遇到不需要请求体的命令时会报错)

代码语言:javascript
复制
{
 "title":"HUAWEI Mate 40",
 "category":"华为手机",
 "images":"https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
 "price":6099
}

点击Send发送请求:

返回结果:

代码语言:javascript
复制
{
    "_index": "shopping",
    "_type": "_doc",
    "_id": "1",
    "_version"【版本】: 3,
    "result"【结果】: "updated",// updated 表示数据被更新
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 3,
    "_primary_term": 1
}
图片
图片
  • 局部修改(非幂等性)
代码语言:javascript
复制
POST http://127.0.0.1:9200/shopping/_update/1

请求体:

代码语言:javascript
复制
{ 
    "doc": {
        "category":"国产手机" // 点名要修改的字段为"category"
        //这里可以写其它需要修改的字段
    }
}

返回结果:

代码语言:javascript
复制
{
    "_index": "shopping",
    "_type": "_doc",
    "_id": "1",
    "_version": 2,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 16,
    "_primary_term": 1
}
图片
图片
删除文档
  • 通过ID删除
代码语言:javascript
复制
DELETE http://127.0.0.1:9200/shopping/_doc/1

返回结果:

代码语言:javascript
复制
{
    "_index": "shopping",
    "_type": "_doc",
    "_id": "1",
    "_version": 5,
    "result": "deleted",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 5,
    "_primary_term": 1
}
图片
图片
  • 通过条件删除
代码语言:javascript
复制
POST http://127.0.0.1:9200/shopping/_delete_by_query

请求体:

代码语言:javascript
复制
{
 "query":{
    "match":{
        "price":6299
    }
 }
}

返回结果:

代码语言:javascript
复制
{
    "took"【请求时间】: 24,
    "timed_out"【是否超时】: false,
    "total"【总数】: 3,
    "deleted"【删除数量】: 3,
    "batches": 1,
    "version_conflicts": 0,
    "noops": 0,
    "retries": {
        "bulk": 0,
        "search": 0
    },
    "throttled_millis": 0,
    "requests_per_second": -1.0,
    "throttled_until_millis": 0,
    "failures": []
}
图片
图片

同理如果要删除索引下全部数据,只需要改请求体条件即可:

代码语言:javascript
复制
{
 "query": {
    "match_all": {}
  }
}

Kibana

打开Kibana的bin路径下的kibana.bat启动Kibana;

图片
图片

然后浏览器访问5601端口,点击Explore on my own;

图片
图片

在左侧菜单找到Dev Tools;

图片
图片
索引操作
创建索引

相当于关系型数据库中的创建数据库

输入一个PUT命令:

代码语言:javascript
复制
PUT shopping

错误写法(不能有空行):

代码语言:javascript
复制
PUT shopping

点击代码右侧的启动按钮,可以在右侧看到创建成功的提示 返回结果:

代码语言:javascript
复制
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "shopping"
}
图片
图片

重复添加时会报错: 返回结果:

代码语言:javascript
复制
{
  "error" : {
    "root_cause" : [
      {
        "type" : "resource_already_exists_exception",
        "reason" : "index [shopping/oTiQnf9UT--dwgsZ_2wBow] already exists",
        "index_uuid" : "oTiQnf9UT--dwgsZ_2wBow",
        "index" : "shopping"
      }
    ],
    "type" : "resource_already_exists_exception",
    "reason" : "index [shopping/oTiQnf9UT--dwgsZ_2wBow] already exists",
    "index_uuid" : "oTiQnf9UT--dwgsZ_2wBow",
    "index" : "shopping"
  },
  "status" : 400
}
查询索引

输入一个GET命令,来查询所有索引;(cat 表示查看的意思,indices 表示索引,相当于像 MySQL 中的 show tables)

代码语言:javascript
复制
GET _cat/indices?v

返回结果:

代码语言:javascript
复制
health status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   .geoip_databases                fjfmnkm2RZKMHtGbBQGweg   1   0         41           39     40.1mb         40.1mb
green  open   .kibana_7.15.0_001              mKyI2n3oSaK-U7-BIepohA   1   0         51            3      2.3mb          2.3mb
green  open   .apm-custom-link                4m9W5TxCRJSs8I6GqDepMw   1   0          0            0       208b           208b
green  open   .apm-agent-configuration        731dsjx0TaWdnmGqyKBvQQ   1   0          0            0       208b           208b
green  open   .kibana-event-log-7.15.0-000001 2__Yx8BARWGwOgCarYgezA   1   0          1            0        6kb            6kb
green  open   .kibana_task_manager_7.15.0_001 bWnZfG6aQPyCXa8j23Mimw   1   0         15         2124    286.4kb        286.4kb
yellow open   shopping                        pjEDILI4TjCq1zG2rGfiww   1   1          0            0       208b           208b
图片
图片

可以看到ElasticSearch请求方式用小写也能执行,但是左侧会报错误提醒

查询单个索引

代码语言:javascript
复制
GET shopping

返回结果:

代码语言:javascript
复制
{
  "shopping" : {
    "aliases" : { },
    "mappings" : { },
    "settings" : {
      "index" : {
        "routing" : {
          "allocation" : {
            "include" : {
              "_tier_preference" : "data_content"
            }
          }
        },
        "number_of_shards" : "1",
        "provided_name" : "shopping",
        "creation_date" : "1633512085101",
        "number_of_replicas" : "1",
        "uuid" : "pjEDILI4TjCq1zG2rGfiww",
        "version" : {
          "created" : "7150099"
        }
      }
    }
  }
}
图片
图片
删除索引
代码语言:javascript
复制
DELETE shopping

返回结果:

代码语言:javascript
复制
{
  "acknowledged" : true
}
图片
图片
文档操作
创建文档

这里的文档就相当于MySQL中的表中的数据

发送一个POST请求,创建文档,文档的格式为JSON:

  • POST

选择POST请求(由于此处没有指定ID为非幂等性操作,所以只能用POST):

简单理解幂等性:多次操作与一次操作的结果相同,即为幂等性操作;反之 此例中由于没有指定ID,所以ID为随机生成,导致多次操作与一次操作的结果不同

代码语言:javascript
复制
POST shopping/_doc 
{
 "title":"HUAWEI Mate 40 Pro",
 "category":"华为手机",
 "images":"https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
 "price":6299
}

点击右侧运行按钮运行

返回结果(附解释):

代码语言:javascript
复制
{
    "_index"【索引】: "shopping",
    "_type"【类型-文档】: "_doc",
    "_id"【唯一标识】: "qXSbVXwBGcQwpwaptCcq", //可以类比为 MySQL 中的主键,随机生成
    "_version"【版本】: 1, //对数据的操作,都会更新版本
    "result"【结果】: "created",//这里的 create 表示创建成功
    "_shards"【分片】: {
        "total"【分片 - 总数】: 2,
        "successful"【分片 - 成功】: 1,
        "failed"【分片 - 失败】: 0
    },
    "_seq_no": 6,
    "_primary_term": 1
}
图片
图片
  • PUT/POST

上面的数据创建后,由于没有指定数据唯一性标识(ID)(也就是主键),默认情况下,ES 服务器会随机生成一个。 如果想要自定义唯一性标识,需要在创建时指定(此时就变成了幂等性操作,因此可以使用POST和PUT两种请求方式)

代码语言:javascript
复制
PUT shopping/_doc/1
{
 "title":"HUAWEI Mate 40 Pro",
 "category":"华为手机",
 "images":"https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
 "price":6299
}
代码语言:javascript
复制
POST shopping/_doc/1
{
 "title":"HUAWEI Mate 40 Pro",
 "category":"华为手机",
 "images":"https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
 "price":6299
}

返回结果:

代码语言:javascript
复制
{
    "_index": "shopping",
    "_type": "_doc",
    "_id": "1", // 可以看到ID为指定的 1
    "_version": 2,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 8,
    "_primary_term": 1
}
图片
图片
查看文档
  • 通过主键(ID)查询,此处的1为刚才创建的ID
代码语言:javascript
复制
GET shopping/_doc/1

返回结果:

代码语言:javascript
复制
{
  "_index" : "shopping",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "_seq_no" : 8,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "title" : "HUAWEI Mate 40 Pro",
    "category" : "华为手机",
    "images" : "https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
    "price" : 6299
  }
}
图片
图片
  • 通过_search查询目标索引全部数据
代码语言:javascript
复制
GET shopping/_search
代码语言:javascript
复制
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "shopping",
        "_type" : "_doc",
        "_id" : "qHRAVXwBGcQwpwap0CcF",
        "_score" : 1.0,
        "_source" : {
          "title" : "HUAWEI Mate 40 Pro",
          "category" : "华为手机",
          "images" : "https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
          "price" : 6299
        }
      },
      {
        "_index" : "shopping",
        "_type" : "_doc",
        "_id" : "qXSbVXwBGcQwpwaptCcq",
        "_score" : 1.0,
        "_source" : {
          "title" : "HUAWEI Mate 40 Pro",
          "category" : "华为手机",
          "images" : "https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
          "price" : 6299
        }
      },
      {
        "_index" : "shopping",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "title" : "HUAWEI Mate 40 Pro",
          "category" : "华为手机",
          "images" : "https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
          "price" : 6299
        }
      }
    ]
  }
}
图片
图片
修改文档
  • 全量修改

请求体:(请求完成后记得把请求体删除,否则遇到不需要请求体的命令时会报错)

代码语言:javascript
复制
PUT shopping/_doc/1
{
  "title":"HUAWEI Mate 40",
  "category":"华为手机",
  "images":"https://res.vmallres.com/pimages//product/6941487225231/428_428_797B0D9B0E6215FA6F6E7D20C3856D594385808C2EB3B3C2mp.png",
  "price":6099
}

返回结果:

代码语言:javascript
复制
{
  "_index" : "shopping",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 3,
  "result" : "updated", // updated 表示数据被更新
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 9,
  "_primary_term" : 1
}
图片
图片
  • 局部修改(非幂等性)
代码语言:javascript
复制
POST http://127.0.0.1:9200/shopping/_update/1

请求体:

代码语言:javascript
复制
POST /shopping/_update/1
{ 
    "doc": {
        "title":"华为 Mate 40",//点名要修改的字段为"title"
        "category":"国产手机" //点名要修改的字段为"category"
        //这里可以写其它需要修改的字段
    }
}

返回结果

代码语言:javascript
复制
{
  "_index" : "shopping",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 4,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 10,
  "_primary_term" : 1
}
图片
图片
删除文档
  • 通过ID删除
代码语言:javascript
复制
DELETE /shopping/_doc/1

返回结果:

代码语言:javascript
复制
{
  "_index" : "shopping",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 5,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 11,
  "_primary_term" : 1
}
图片
图片
  • 通过条件删除
代码语言:javascript
复制
POST /shopping/_delete_by_query
{
   "query":{
    "match":{
        "price":6299
    }
 }
}

返回结果:

代码语言:javascript
复制
{
  "took" 【请求时间】: 521,
  "timed_out" 【是否超时】: false,
  "total" 【总数】: 2,
  "deleted" 【删除数量】: 2,
  "batches" : 1,
  "version_conflicts" : 0,
  "noops" : 0,
  "retries" : {
    "bulk" : 0,
    "search" : 0
  },
  "throttled_millis" : 0,
  "requests_per_second" : -1.0,
  "throttled_until_millis" : 0,
  "failures" : [ ]
}
图片
图片

同理如果要删除索引下全部数据,只需要改请求体条件即可:

代码语言:javascript
复制
{
 "query": {
    "match_all": {}
  }
}

对比

一图简单对比Postman和Kibana使用ES命令方式区别:

图片
图片

由于后面示例都是用的Kibana,继续用Postman的可自行参照此图,根据示例中的Kibana进行类比

映射关系

索引库(index)中的映射类似于数据库(database)中的表结构(table)。 创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型 下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)。

映射数据说明:

  • 字段名:任意填写,下面指定许多属性,例如:title、subtitle、images、price
  • type:类型,Elasticsearch 中支持的数据类型非常丰富,说几个关键的:
    • String 类型,又分两种: text:可分词
    • keyword:不可分词,数据会作为完整字段进行匹配
  • Numerical:数值类型,分两类
    • 基本数据类型:long、integer、short、byte、double、float、half_float
    • 浮点数的高精度类型:scaled_float
  • Date:日期类型
  • Array:数组类型
  • Object:对象
  • index:是否索引,默认为 true,也就是说你不进行任何配置,所有字段都会被索引。
    • true:字段会被索引,则可以用来进行搜索
    • false:字段不会被索引,不能用来搜索
  • store:是否将数据进行独立存储,默认为 false 原始的文本会存储在_source 里面,默认情况下其他提取出来的字段都不是独立存储 的,是从_source 里面提取出来的。当然你也可以独立的存储某个字段,只要设置 “store”: true 即可,获取独立存储的字段要比从_source 中解析快得多,但是也会占用 更多的空间,所以要根据实际业务需求来设置。
  • analyzer:分词器,这里的 ik_max_word 即使用 ik 分词器
创建映射关系
  • 方法一:

首先创建索引

代码语言:javascript
复制
PUT student

然后创建映射关系

代码语言:javascript
复制
PUT student/_mapping
{
 "properties": {
  "name":{
     "type": "text",
     "index": true
  },
  "nickname":{
     "type": "text",
     "index": true
  },
  "sex":{
     "type": "keyword",
     "index": true
   },
   "age":{
     "type": "long",
     "index": false
   }
 }
}

返回结果:

代码语言:javascript
复制
{
  "acknowledged" : true
}
  • 方法二: 直接创建索引并与映射关联
代码语言:javascript
复制
PUT student2
{
  "settings": {}, 
  "mappings": {
   "properties": {
    "name":{
      "type": "text",
       "index": true
   },
   "nickname":{
       "type": "keyword",
       "index": true
   },
   "sex":{
       "type": "keyword",
       "index": true
    },
    "age":{
      "type": "long",
      "index": false
    }
   }
  }
}

返回结果:

代码语言:javascript
复制
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "student2"
}
查看映射关系
代码语言:javascript
复制
GET student/_mapping

返回结果:

代码语言:javascript
复制
{
  "student" : {
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "long",
          "index" : false
        },
        "name" : {
          "type" : "text"
        },
        "nickname" : {
          "type" : "text"
        },
        "sex" : {
          "type" : "keyword"
        }
      }
    }
  }
}

高级查询

为了方便演示,这里不使用系统自动给的映射,而是自行创建映射

代码语言:javascript
复制
PUT phone
{   
  "settings": {},
  "mappings": {    
    "properties": {   
      "name":{     
        "type": "text",     
        "index": true        
      },   
      "vendor":{
        "type": "keyword",     
        "index": true   
      },   
      "pid":{     
        "type": "long",
        "index": false
      },
      "price":{     
        "type": "long",
        "index": true
      },
      "content":{     
        "type": "text",
        "index": true
      },
      "area":{     
        "type": "keyword",
        "index": true
      }
    }   
  } 
} 

创建完映射后,创建数据

代码语言:javascript
复制
POST /phone/_doc/1001  //这里的_doc即为文档类型,ElasticSearch 7.0已不支持自定义,只能为_doc
{ 
  "name":"小米手机", 
  "vendor":"小米",
  "pid":"1001",
  "price":3999 ,
  "content":"MIUI Based on Android OS",
  "area": "China"
}

POST /phone/_doc/1002
{ 
  "name":"小米手机Pro", 
  "vendor":"小米",
  "pid":"1002",
  "price":4999 ,
  "content":"MIUI Not based on Harmony OS",
  "area": "China"
}

POST /phone/_doc/1003
{ 
  "name":"华为手机", 
  "vendor":"华为",、
  "pid":"1003",
  "price":4488 ,
  "content":"HarmonyOS Based on Harmony OS",
  "area": "China"
}
POST /phone/_doc/1004
{ 
  "name":"华为手机", 
  "vendor":"华为",
  "pid":"1004",
  "price":6488,
  "content":"HarmonyOS Not based on Android OS",
  "area": "China"
}

POST /phone/_doc/1005
{ 
  "name":"苹果手机", 
  "vendor":"Apple",
  "pid":"1005",
  "price":5199,
  "content":"IOS Not based on Android OS",
  "area": "American"
}
POST /phone/_doc/1006
{ 
  "name":"苹果手机", 
  "vendor":"Apple",
  "pid":"1006",
  "price":7999,
  "content":"IOS Not based on Harmony OS",
  "area": "American"
}
全量查询(match_all)
代码语言:javascript
复制
GET phone/_search
{   
  "query": { // "query":这里的 query 代表一个查询对象,里面可以有不同的查询属性
    "match_all": {}   // "match_all":查询类型,例如:match_all(代表查询所有), match,term , range 等等;
    // "match_all":{查询条件}:match_all下写查询条件,根据类型的不同,写法也有差异
  } 
} 

代码语言:javascript
复制
{
  "took" 【查询花费时间,单位毫秒】: 0,
  "timed_out"【是否超时】 : false,
  "_shards"【分片信息】 : {
    "total"【总数】 : 1,
    "successful"【成功】 : 1,
    "skipped" 【忽略】: 0,
    "failed"【失败】 : 0
  },
  "hits"【搜索命中结果】 : {
    "total" 【搜索条件匹配的文档总数】: {
      "value"【总命中计数的值】 : 6,
      "relation"【计数规则】 : "eq" //eq 表示计数准确, gte 表示计数不准确
    },
    "max_score" 【匹配度分值】: 1.0,
    "hits" 【命中结果集合】: [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1001",
        "_score" : 1.0,
        "_source" : {
          "name" : "小米手机",
          "vendor" : "小米",
          "pid" : "1001",
          "price" : 3999,
          "content" : "MIUI Based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1002",
        "_score" : 1.0,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1002",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1003",
        "_score" : 1.0,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1003",
          "price" : 4488,
          "content" : "HarmonyOS Based on Harmony OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1004",
        "_score" : 1.0,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1004",
          "price" : 6488,
          "content" : "HarmonyOS Not based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1005",
        "_score" : 1.0,
        "_source" : {
          "name" : "苹果手机",
          "vendor" : "Apple",
          "pid" : "1005",
          "price" : 5199,
          "content" : "IOS Not based on Android OS",
          "area" : "American"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1006",
        "_score" : 1.0,
        "_source" : {
          "name" : "苹果手机",
          "vendor" : "Apple",
          "pid" : "1006",
          "price" : 7999,
          "content" : "IOS Not based on Harmony OS",
          "area" : "American"
        }
      }
    ]
  }
}
图片
图片
匹配查询(match)

match 匹配类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是 or 的关系 1)直接通过请求路径查询(不推荐,中文容易出现乱码)

代码语言:javascript
复制
GET phone/_search?q=content:OS Android Not on

返回结果:

代码语言:javascript
复制
{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 6,
      "relation" : "eq"
    },
    "max_score" : 1.2530423,
    "hits" : [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1004",
        "_score" : 1.2530423,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1004",
          "price" : 6488,
          "content" : "HarmonyOS Not based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1005",
        "_score" : 1.2530423,
        "_source" : {
          "name" : "苹果手机",
          "vendor" : "Apple",
          "pid" : "1005",
          "price" : 5199,
          "content" : "IOS Not based on Android OS",
          "area" : "American"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1001",
        "_score" : 0.88390386,
        "_source" : {
          "name" : "小米手机",
          "vendor" : "小米",
          "pid" : "1001",
          "price" : 3999,
          "content" : "MIUI Based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1002",
        "_score" : 0.5761833,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1002",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1006",
        "_score" : 0.5761833,
        "_source" : {
          "name" : "苹果手机",
          "vendor" : "Apple",
          "pid" : "1006",
          "price" : 7999,
          "content" : "IOS Not based on Harmony OS",
          "area" : "American"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1003",
        "_score" : 0.15571001,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1003",
          "price" : 4488,
          "content" : "HarmonyOS Based on Harmony OS",
          "area" : "China"
        }
      }
    ]
  }
}

查询条件被自动分词,所有content字段中包含“OS、Android、Not、on”的文档均会被检索出来

图片
图片

2)通过请求体查询

代码语言:javascript
复制
GET phone/_search
{   
  "query": {     
    "match": {
      "content": "OS Android Not on"
    }   
  } 
} 

返回结果和上面一样 为了更直观的显示我们可以使用Search Profiler进行查询:

图片
图片

可以很直观的看到查询条件被分成了四个字段“OS、Android、Not、on”

测试text类型映射:

代码语言:javascript
复制
GET phone/_search
{   
  "query": {     
    "match": {
      "name": "华果"
    }   
  } 
} 

返回结果:

代码语言:javascript
复制
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.0467482,
    "hits" : [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1003",
        "_score" : 1.0467482,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1003",
          "price" : 4488,
          "content" : "HarmonyOS Based on Harmony OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1004",
        "_score" : 1.0467482,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1004",
          "price" : 6488,
          "content" : "HarmonyOS Not based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1005",
        "_score" : 1.0467482,
        "_source" : {
          "name" : "苹果手机",
          "vendor" : "Apple",
          "pid" : "1005",
          "price" : 5199,
          "content" : "IOS Not based on Android OS",
          "area" : "American"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1006",
        "_score" : 1.0467482,
        "_source" : {
          "name" : "苹果手机",
          "vendor" : "Apple",
          "pid" : "1006",
          "price" : 7999,
          "content" : "IOS Not based on Harmony OS",
          "area" : "American"
        }
      }
    ]
  }
}

查询字段中的华和果自动被分词了,因此所有name中包含华和果的文档全被检索出来了

图片
图片
图片
图片

同样可以看到关键词被分成了华和果两个字段

测试keyword类型映射:

代码语言:javascript
复制
GET phone/_search
{   
  "query": {     
    "match": {
      "vendor": "小华"
    }   
  } 
} 

返回结果(未查到符合要求文档):

代码语言:javascript
复制
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}
图片
图片
图片
图片

可以看到由于vendor字段被设置了keyword映射,所以查询关键词并没有被分词;所以必须输入该字段的完整值进行查询

代码语言:javascript
复制
GET phone/_search
{   
  "query": {     
    "match": {
      "vendor": "小米"
    }   
  } 
} 

返回结果:

代码语言:javascript
复制
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0296195,
    "hits" : [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1001",
        "_score" : 1.0296195,
        "_source" : {
          "name" : "小米手机",
          "vendor" : "小米",
          "pid" : "1001",
          "price" : 3999,
          "content" : "MIUI Based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1002",
        "_score" : 1.0296195,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1002",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        }
      }
    ]
  }
}

测试index为false(不能被检索):

代码语言:javascript
复制
GET phone/_search
{   
  "query": {     
    "match": {
      "pid": "1001"
    }   
  } 
} 

返回结果:(提示错误信息)

代码语言:javascript
复制
{
  "error" : {
    "root_cause" : [
      {
        "type" : "query_shard_exception",
        "reason" : "failed to create query: Cannot search on field [pid] since it is not indexed.",
        "index_uuid" : "b4aDx_95SMC49YIjLsLwrw",
        "index" : "phone"
      }
    ],
    "type" : "search_phase_execution_exception",
    "reason" : "all shards failed",
    "phase" : "query",
    "grouped" : true,
    "failed_shards" : [
      {
        "shard" : 0,
        "index" : "phone",
        "node" : "a7zlNhivS7iCgDBR91d53Q",
        "reason" : {
          "type" : "query_shard_exception",
          "reason" : "failed to create query: Cannot search on field [pid] since it is not indexed.",
          "index_uuid" : "b4aDx_95SMC49YIjLsLwrw",
          "index" : "phone",
          "caused_by" : {
            "type" : "illegal_argument_exception",
            "reason" : "Cannot search on field [pid] since it is not indexed."
          }
        }
      }
    ]
  },
  "status" : 400
}
字段匹配查询(multi_match)

multi_match 与match 的区别就是它可以在多个字段中进行查询

代码语言:javascript
复制
GET phone/_search
{   
  "query": {
    "multi_match": {     
      "query": "华MIUI",
      "fields": ["name", "content"]
   } 
  }
} 

查询在name和content字段中包含华和MIUI的文档

返回结果:

代码语言:javascript
复制
{
  "took" : 14,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.0816789,
    "hits" : [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1001",
        "_score" : 1.0816789,
        "_source" : {
          "name" : "小米手机",
          "vendor" : "小米",
          "pid" : "1001",
          "price" : 3999,
          "content" : "MIUI Based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1003",
        "_score" : 1.0467482,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1003",
          "price" : 4488,
          "content" : "HarmonyOS Based on Harmony OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1004",
        "_score" : 1.0467482,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1004",
          "price" : 6488,
          "content" : "HarmonyOS Not based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1002",
        "_score" : 1.0054247,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1002",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        }
      }
    ]
  }
}
关键字精确查询(term)

term 查询,精确的关键词匹配查询,不对查询条件进行分词。

代码语言:javascript
复制
GET phone/_search
{   
  "query": {
    "term": {     
      "name": {         
        "value": "小米手机"
      } 
    } 
  }
}

返回结果:(未查询到)

代码语言:javascript
复制
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

由于text类型默认会被自动分词,所以存入name字段的值:“小米手机”会被自动分成“小、米、手、机”四个字,因此当我们进行精确匹配查询“小米手机”时就会查询不到;只有当查询“小、米、手、机”四个字的任意字时才会匹配到;如果name字段被设为keyword映射,则只有当查询的关键词为“小米手机”时才会进行匹配

多关键字精确查询(terms)

terms查询和term查询的区别是它可以指定多值进行匹配查询,并且只需要匹配一个值即为满足查询条件;类似于mysql 的in 。

代码语言:javascript
复制
GET phone/_search
{   
  "query": {
    "terms": {     
      "vendor": ["小米", "华为"] 
    } 
  }
}

返回结果:

代码语言:javascript
复制
{
  "took" : 18,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1001",
        "_score" : 1.0,
        "_source" : {
          "name" : "小米手机",
          "vendor" : "小米",
          "pid" : "1001",
          "price" : 3999,
          "content" : "MIUI Based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1002",
        "_score" : 1.0,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1002",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1003",
        "_score" : 1.0,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1003",
          "price" : 4488,
          "content" : "HarmonyOS Based on Harmony OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1004",
        "_score" : 1.0,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1004",
          "price" : 6488,
          "content" : "HarmonyOS Not based on Android OS",
          "area" : "China"
        }
      }
    ]
  }
}
指定查询字段(_source)

默认情况下,ElasticSearch会将保存在_source中的所有字段都返回。因此我们可以自定义返回的字段

代码语言:javascript
复制
GET phone/_search
{   
  "_source": ["name", "area"],
  "query": {     
    "match": {
      "name": "小华"
    }   
  } 
} 

设置_source只返回name和area字段

返回结果:

代码语言:javascript
复制
{
  "took" : 18,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.0467482,
    "hits" : [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1001",
        "_score" : 1.0467482,
        "_source" : {
          "area" : "China",
          "name" : "小米手机"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1003",
        "_score" : 1.0467482,
        "_source" : {
          "area" : "China",
          "name" : "华为手机"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1004",
        "_score" : 1.0467482,
        "_source" : {
          "area" : "China",
          "name" : "华为手机"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1002",
        "_score" : 0.9517491,
        "_source" : {
          "area" : "China",
          "name" : "小米手机Pro"
        }
      }
    ]
  }
}
过滤字段(includes/excludes)

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

excludes:来指定不想要显示的字段 返回结果: boolmustmust_notshould

代码语言:javascript
复制
GET phone/_search
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "area": "China"
        }
      },
      "must_not": {
        "match": {
          "content": "abc"
        }
      },
      "should": {
        "match": {
          "vendor": "华为"
        }
      }
    }
  }
}
代码语言:javascript
复制
{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.4714522,
    "hits" : [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1003",
        "_score" : 1.4714522,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1003",
          "price" : 4488,
          "content" : "HarmonyOS Based on Harmony OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1004",
        "_score" : 1.4714522,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1004",
          "price" : 6488,
          "content" : "HarmonyOS Not based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1001",
        "_score" : 0.44183272,
        "_source" : {
          "name" : "小米手机",
          "vendor" : "小米",
          "pid" : "1001",
          "price" : 3999,
          "content" : "MIUI Based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1002",
        "_score" : 0.44183272,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1002",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        }
      }
    ]
  }
}

可以看到满足must条件的华为和小米均被查了出来,而符合should要求的华为优先级较高,被排在了前面

范围查询(range)

range 查询找出那些落在指定区间内的数字或者时间。range 查询允许以下字符

操作符

说明

gt

>

gte

>=

lt

<

lte

<=

代码语言:javascript
复制
GET phone/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 4000,
        "lte": 5000
      }
    }
  }
}

返回结果:

代码语言:javascript
复制
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1002",
        "_score" : 1.0,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1002",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1003",
        "_score" : 1.0,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1003",
          "price" : 4488,
          "content" : "HarmonyOS Based on Harmony OS",
          "area" : "China"
        }
      }
    ]
  }
}
模糊查询(wildcard)

模糊查询效率较慢,因此不推荐使用;和大部分模糊匹配一样,使用*或者?进行占位替代; ​

代码语言:javascript
复制
GET phone/_search
{
  "query": {
    "wildcard": {
      "area": {
        "value": "Am*"
      }
    }
  }
}

返回结果:

代码语言:javascript
复制
{
  "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" : "phone",
        "_type" : "_doc",
        "_id" : "1005",
        "_score" : 1.0,
        "_source" : {
          "name" : "苹果手机",
          "vendor" : "Apple",
          "pid" : "1005",
          "price" : 5199,
          "content" : "IOS Not based on Android OS",
          "area" : "American"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1006",
        "_score" : 1.0,
        "_source" : {
          "name" : "苹果手机",
          "vendor" : "Apple",
          "pid" : "1006",
          "price" : 7999,
          "content" : "IOS Not based on Harmony OS",
          "area" : "American"
        }
      }
    ]
  }
}

因为是模糊查询,所以不受keyword映射影响,但是仍然会受到分词器的影响,比如下面实例中的模糊查询name为“小米”的文档,而上面示例已经说了,“小米手机”已经被分词成了四个独立的字,因此通过“小米”去模糊查询,仍然是查询不到的

代码语言:javascript
复制
GET phone/_search
{
  "query": {
    "wildcard": {
      "name": {
        "value": "小米"
      }
    }
  }
}
单字段排序(sort)

sort 可以按照不同的字段进行排序,并且通过order 指定排序的方式(desc 降序,asc升序)。

代码语言:javascript
复制
GET phone/_search
{   
  "query": {
    "match": {"area": "China"}
  },
  "sort": {     
    "price": {
      "order": "desc"
    }   
  } 
} 

返回结果:

代码语言:javascript
复制
{
  "took" : 15,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1004",
        "_score" : null,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1004",
          "price" : 6488,
          "content" : "HarmonyOS Not based on Android OS",
          "area" : "China"
        },
        "sort" : [
          6488
        ]
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1002",
        "_score" : null,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1002",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        },
        "sort" : [
          4999
        ]
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1003",
        "_score" : null,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1003",
          "price" : 4488,
          "content" : "HarmonyOS Based on Harmony OS",
          "area" : "China"
        },
        "sort" : [
          4488
        ]
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1001",
        "_score" : null,
        "_source" : {
          "name" : "小米手机",
          "vendor" : "小米",
          "pid" : "1001",
          "price" : 3999,
          "content" : "MIUI Based on Android OS",
          "area" : "China"
        },
        "sort" : [
          3999
        ]
      }
    ]
  }
}
多字段排序(sort)

为方便测试,添加一个只有ID不同的数据:

代码语言:javascript
复制
POST /phone/_doc/1007
{ 
  "name":"小米手机Pro", 
  "vendor":"小米",
  "pid":"1007",
  "price":4999 ,
  "content":"MIUI Not based on Harmony OS",
  "area": "China"
}

开始测试:

代码语言:javascript
复制
GET phone/_search
{   
  "query": {
    "match": {"name": "小米"}
  },
  "sort": [
    {
      "price": {
        "order": "desc"
      }   
    },
    {
      "_id": {
        "order": "asc"
      }
    }
  ]
} 

先按价格降序,然后按_id升序

返回结果:

代码语言:javascript
复制
{
  "took" : 18,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1002",
        "_score" : null,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1002",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        },
        "sort" : [
          4999,
          "1002"
        ]
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1007",
        "_score" : null,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1007",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        },
        "sort" : [
          4999,
          "1007"
        ]
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1001",
        "_score" : null,
        "_source" : {
          "name" : "小米手机",
          "vendor" : "小米",
          "pid" : "1001",
          "price" : 3999,
          "content" : "MIUI Based on Android OS",
          "area" : "China"
        },
        "sort" : [
          3999,
          "1001"
        ]
      }
    ]
  }
}

测试完成后,删除刚刚添加的数据 ​

高亮查询(highlight)

Elasticsearch 可以对查询内容中的关键字部分,进行标签和样式(高亮)的设置。 在使用match 查询的同时,加上一个highlight 属性(可以不设置,不设置则为默认值):

pre_tags:前置标签 (默认为em标签)

post_tags:后置标签 (默认为em标签)

fields:需要高亮的字段

title:这里声明title 字段需要高亮,后面可以为这个字段设置特有配置

返回结果:

代码语言:javascript
复制
{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.699713,
    "hits" : [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1001",
        "_score" : 1.699713,
        "_source" : {
          "name" : "小米手机",
          "vendor" : "小米",
          "pid" : "1001",
          "price" : 3999,
          "content" : "MIUI Based on Android OS",
          "area" : "China"
        },
        "highlight" : {
          "name" : [
            "<font color='red'>小</font><font color='red'>米</font>手机"
          ]
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1002",
        "_score" : 1.5478239,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1002",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        },
        "highlight" : {
          "name" : [
            "<font color='red'>小</font><font color='red'>米</font>手机Pro"
          ]
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1007",
        "_score" : 1.5478239,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1007",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        },
        "highlight" : {
          "name" : [
            "<font color='red'>小</font><font color='red'>米</font>手机Pro"
          ]
        }
      }
    ]
  }
}

因为是html语法,所以返回结果里面只有文字,而不是直接显示效果

分页查询(from)

from:当前页的起始索引,默认从0 开始。 from = (页数 - 1) * size 【即from为0时,为第一页,以此类推】 size:每页显示多少条

代码语言:javascript
复制
GET phone/_search
{   
  "query": {
    "match_all": {}
  },
  "sort": {
    "price": {
      "order": "asc"
    }
  },
  "from": 0,
  "size": 2
} 

返回结果:

代码语言:javascript
复制
{
  "took" : 10,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 7,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1001",
        "_score" : null,
        "_source" : {
          "name" : "小米手机",
          "vendor" : "小米",
          "pid" : "1001",
          "price" : 3999,
          "content" : "MIUI Based on Android OS",
          "area" : "China"
        },
        "sort" : [
          3999
        ]
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1003",
        "_score" : null,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1003",
          "price" : 4488,
          "content" : "HarmonyOS Based on Harmony OS",
          "area" : "China"
        },
        "sort" : [
          4488
        ]
      }
    ]
  }
}
聚合查询(aggs)

聚合允许使用者对es文档进行统计分析,类似与MySQL中的group by

度量聚合

例如取最大值(max)、最小值(min)、平均值(avg)、总数(count)、 去重后求总数(cardinality)、返回所有度量类型的统计(stats)等等。

代码语言:javascript
复制
GET phone/_search
{
  "aggs": { //aggs表示聚合操作
    "sum_price": { //sum_price为自定义的分组名 
      "sum": { //sum表示求和
        "field": "price" //分组字段:price
      }
    }
  }
}

返回结果:

代码语言:javascript
复制
{
  "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" : "phone",
        "_type" : "_doc",
        "_id" : "1001",
        "_score" : 1.0,
        "_source" : {
          "name" : "小米手机",
          "vendor" : "小米",
          "pid" : "1001",
          "price" : 3999,
          "content" : "MIUI Based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1002",
        "_score" : 1.0,
        "_source" : {
          "name" : "小米手机Pro",
          "vendor" : "小米",
          "pid" : "1002",
          "price" : 4999,
          "content" : "MIUI Not based on Harmony OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1003",
        "_score" : 1.0,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1003",
          "price" : 4488,
          "content" : "HarmonyOS Based on Harmony OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1004",
        "_score" : 1.0,
        "_source" : {
          "name" : "华为手机",
          "vendor" : "华为",
          "pid" : "1004",
          "price" : 6488,
          "content" : "HarmonyOS Not based on Android OS",
          "area" : "China"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1005",
        "_score" : 1.0,
        "_source" : {
          "name" : "苹果手机",
          "vendor" : "Apple",
          "pid" : "1005",
          "price" : 5199,
          "content" : "IOS Not based on Android OS",
          "area" : "American"
        }
      },
      {
        "_index" : "phone",
        "_type" : "_doc",
        "_id" : "1006",
        "_score" : 1.0,
        "_source" : {
          "name" : "苹果手机",
          "vendor" : "Apple",
          "pid" : "1006",
          "price" : 7999,
          "content" : "IOS Not based on Harmony OS",
          "area" : "American"
        }
      }
    ]
  },
  "aggregations" : {
    "max_price" : {
      "value" : 33172.0
    }
  }
}

在查询结果底部的aggregations字段中可以看到得到的相加结果为33172.0

桶聚合查询

在已有的分组条件下再进行聚合即为桶聚合,相当于MySQL中的group by 语句;桶聚合返回很多子集,并限定输入数据到一个特殊的叫做桶的子集中。可以把桶聚合想象成 类似切面功能的东西。

  • term聚合:词条的聚合

terms聚合为字段中每个词条返回一个桶。允许你生成字段每个值的统计;

  • range聚合和date range聚合

范围聚合和时间范围聚合

  • 桶嵌套

多个聚合的嵌套即为桶嵌套

后记

  • Elasticsearch 是使用 java 开发的,7.8 版本及以上需要 JDK 版本 1.8 以上,默认安装包带有 jdk 环境,如果系统配置了JDK环境变量,会默认使用系统配置的 JDK,如果没有配置使用自带的 JDK,一般建议使用系统配置的 JDK。
  • 双击启动窗口闪退,通过路径访问追踪错误,如果是“空间不足”,可以尝试修改config/jvm.options 配置文件
代码语言:javascript
复制
# 设置 JVM 初始内存为 1G。此值可以设置与-Xmx 相同,以避免每次垃圾回收完成后 JVM 重新分配内存 # Xms represents the initial size of total heap space # 设置 JVM 最大可用内存为 1G # Xmx represents the maximum size of total heap space 
-Xms1g 
-Xmx1g

中文支持

在Kiabana的配置文件中修改,然后重启Kiabana即可:

代码语言:javascript
复制
# Specifies locale to be used for all localizable strings, dates and number formats.
# Supported languages are the following: English - en , by default , Chinese - zh-CN .
i18n.locale: "zh-CN"

可视化操作

直接对索引操作:

图片
图片

文档的可视化操作

首先在左侧菜单进入Stack Management,然后选择索引模式新建一个索引模式,首次会进行引导

图片
图片
图片
图片

创建完成后,可以点击创建的索引进入详情页,进行操作,也可以直接在右上角创建索引模式继续创建索引

图片
图片

然后在左侧菜单选择Discover,就可以对文档进行可视化操作了

图片
图片
图片
图片
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-10-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
    • 下载安装
      • RESTful
        • 第三方工具
          • 数据格式
          • HTTP操作
            • Postman
              • 索引操作
              • 文档操作
            • Kibana
              • 索引操作
              • 文档操作
            • 对比
              • 映射关系
                • 创建映射关系
                • 查看映射关系
              • 高级查询
                • 全量查询(match_all)
                • 匹配查询(match)
                • 字段匹配查询(multi_match)
                • 关键字精确查询(term)
                • 多关键字精确查询(terms)
                • 指定查询字段(_source)
                • 过滤字段(includes/excludes)
                • 范围查询(range)
                • 模糊查询(wildcard)
                • 单字段排序(sort)
                • 多字段排序(sort)
                • 高亮查询(highlight)
                • 分页查询(from)
                • 聚合查询(aggs)
            • 后记
              • 中文支持
                • 可视化操作
                相关产品与服务
                云数据库 MySQL
                腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档