后端 --- Elasticsearch学习笔记(入门篇)(二)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 后端 --- Elasticsearch学习笔记(入门篇)

删除文档信息

想要删除文档信息其实很简单,只是使用 DELETE 方法即可。如下

查询文档信息

检索单条信息

使用HTTP GET 请求,并指定索引、类型和ID进行查询。如下

GET /learn/user/1


_primary_term_seq_no{
  "_index" : "learn",
  "_type" : "user",
  "_id" : "1",
  "_version" : 2,
  "_seq_no" : 3,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "first_name" : "三",
    "last_name" : "张",
    "age" : 25,
    "about" : "法外狂徒",
    "interests" : [
      "偷盗",
      "抢劫",
      "嘿嘿"
    ]
  }
}

几个字段说明

  • _version: 文档版本号,文档进行更新就会自增1
  • _seq_no:序列号
  • _primary_term:每当主分片发生重新分配时,比如重启,主分片的选举等,_primary_term会递增1。

_primary_term主要是用来恢复数据时处理当多个文档的_seq_no一样时的冲突,比如当一个shard宕机了,raplica需要用到最新的数据,就会根据_primary_term和_seq_no这两个值来拿到最新的document

有的喜欢在请求的查询串上加上pretty参数,如 GET /learn/user/1?pretty,这样只是为了让响应的信息更加可读。

当我们检索一个不存在的文档时,也会给我们返回一个结构体,但是该结构体中的found字段变为了false,同时HTTP响应也会变为 404 Not Found,而不是200 OK,如下所示

{
"_index" : "learn",
"_type" : "user",
"_id" : "5",
"found" : false
}
只检索_source字段

只需在请求后加上 _source 限制符即可。

GET   /learn/user/1/_source

如我们只想要_source 字段中的某些字段,我们可以将请求改为

GET   /learn/user/1/_source/?_source=age,about
检测文档是否存在

从上面我们已经知道,当查询不存在的文档时,HTTP响应会变为404。我们就可以根据这个返回的状态码来确定文档是否存在。

检索多条信息

使用mget API来完成。

mget API 要求有一个 docs 数组作为参数,每个元素包含需要检索文档的元数据, 包括 _index_type_id 。同时如果想要指定字段也可以使用source来指定。

如我们取出learn索引下user的id为1和2的文档,可以写为

GET /_mget
{
   "docs" : [
      {
         "_index" : "learn",
         "_type" :  "user",
         "_id" :    1
      },
      {
         "_index" : "learn",
         "_type" :  "user",
         "_id" :    2,
         "_source": "about"
      }
   ]
}

结果为

{
  "docs" : [
    {
      "_index" : "learn",
      "_type" : "user",
      "_id" : "1",
      "_version" : 2,
      "_seq_no" : 3,
      "_primary_term" : 1,
      "found" : true,
      "_source" : {
        "first_name" : "三",
        "last_name" : "张",
        "age" : 25,
        "about" : "法外狂徒",
        "interests" : [
          "偷盗",
          "抢劫",
          "嘿嘿"
        ]
      }
    },
    {
      "_index" : "learn",
      "_type" : "user",
      "_id" : "2",
      "_version" : 1,
      "_seq_no" : 1,
      "_primary_term" : 1,
      "found" : true,
      "_source" : {
        "about" : "基尼太美"
      }
    }
  ]
}

也可以将索引和类型放在请求URL上,做到简写的目的,如下

GET /learn/user/_mget
{
  "docs": [
    {
      "_id": 1
    },
    {
      "_id": 2,
      "_source": "about"
    }
    ]
}

结果同上面相同。

当然会出现多个文档中有部分文档不存在的情况,这时文档正常返回,状态码仍为200,但是查询不到的文档的found字段显示为false

匹配查询 match,match_all
全搜索

最简单的搜索全部用户的请求:

GET /learn/user/_search
{
    "query": {
        "match_all": {}
    }
}

结果

{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "learn",
        "_type" : "user",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "first_name" : "xk",
          "last_name" : "蔡",
          "age" : 99,
          "about" : "基尼太美",
          "interests" : [
            "唱",
            "跳",
            "rap",
            "篮球"
          ]
        }
      },
      {
        "_index" : "learn",
        "_type" : "user",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "first_name" : "倍",
          "last_name" : "安",
          "age" : 10,
          "about" : "散弹枪狂热者",
          "interests" : [
            "盗窃",
            "篮球"
          ]
        }
      },
      {
        "_index" : "learn",
        "_type" : "user",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "first_name" : "三",
          "last_name" : "张",
          "age" : 25,
          "about" : "法外狂徒",
          "interests" : [
            "偷盗",
            "抢劫",
            "嘿嘿"
          ]
        }
      }
    ]
  }
}

第一部分为:分片副本信息,第二部分 hits 包装的为查询的数据集。

参数解析:

  • took
    该命令请求花费了多长时间,单位:毫秒。
  • timed_out
    搜索是否超时。
  • shards
    搜索分片信息。
  • total
    搜索分片总数。
  • successful
    搜索成功的分片数量。
  • skipped
    没有搜索的分片,跳过的分片。
  • failed
    搜索失败的分片数量。
  • hits
    搜索结果集。项目中,我们需要的一切数据都是从hits中获取。
  • total
    返回多少条数据。
  • max_score
    返回结果中,最大的匹配度分值。
  • hits
    默认查询前十条数据,根据分值降序排序。
  • _index
    索引库名称。
  • _type
    类型名称。
  • _id
    该条数据的id。
  • _score
    关键字与该条数据的匹配度分值。匹配度越高分值就越高。
  • _source
    索引库中类型,返回结果字段,不指定的话,默认全部显示出来。
根据字段信息搜索

查询爱好中包含篮球的用户

GET /learn/user/_search
{
   "query": {
        "match": {
            "interests.keyword": "篮球"
        }
    }
}

结果

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.646255,
    "hits" : [
      {
        "_index" : "learn",
        "_type" : "user",
        "_id" : "2",
        "_score" : 0.646255,
        "_source" : {
          "first_name" : "xk",
          "last_name" : "蔡",
          "age" : 99,
          "about" : "基尼太美",
          "interests" : [
            "唱",
            "跳",
            "rap",
            "篮球"
          ]
        }
      },
      {
        "_index" : "learn",
        "_type" : "user",
        "_id" : "3",
        "_score" : 0.646255,
        "_source" : {
          "first_name" : "倍",
          "last_name" : "安",
          "age" : 10,
          "about" : "散弹枪狂热者",
          "interests" : [
            "盗窃",
            "篮球"
          ]
        }
      }
    ]
  }
}

也可以不使用match匹配查询,而是进行查询字符串 (query-string) 搜索,通过一个URL参数来传递查询信息给搜索接口,如下

GET /learn/user/_search?q=interests:篮球


过滤查询 Filter

假如我们同样要找喜欢打篮球的,但是年龄大于50岁的。我们就可以利用 filter 将查询语句进行一些改变。如下

GET /learn/user/_search
{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "age": {
            "gt": 50
          }
        }
      },
      "must": {
        "match": {
          "interests.keyword": "篮球"
        }
      }
    }
  }
}

这部分是一个 range 过滤器 , 它能找到年龄大于 30 的文档,其中 gt 表示_大于_(great than)。

结果为

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.646255,
    "hits" : [
      {
        "_index" : "learn",
        "_type" : "user",
        "_id" : "2",
        "_score" : 0.646255,
        "_source" : {
          "first_name" : "xk",
          "last_name" : "蔡",
          "age" : 99,
          "about" : "基尼太美",
          "interests" : [
            "唱",
            "跳",
            "rap",
            "篮球"
          ]
        }
      }
    ]
  }
}




短语搜索

我们再为learn索引添一条user文档。

PUT /learn/user/4
{
  "first_name" : "先森",
  "last_name" :  "双口",
  "age" :        10,
  "about" :      "散弹批发商",
  "interests": [ "嘿嘿","游戏" ]
}



再进行匹配查询。查询条件为关于中包含散弹枪的。根据上面所说匹配查询,查询应该这么写


GET /learn/user/_search
{
    "query" : {
        "match" : {
            "about" : "散弹枪"
        }
    }
}

结果

_score{
  "took" : 444,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 2.3385136,
    "hits" : [
      {
        "_index" : "learn",
        "_type" : "user",
        "_id" : "3",
        "_score" : 2.3385136,
        "_source" : {
          "first_name" : "倍",
          "last_name" : "安",
          "age" : 10,
          "about" : "散弹枪狂热者",
          "interests" : [
            "盗窃",
            "篮球"
          ]
        }
      },
      {
        "_index" : "learn",
        "_type" : "user",
        "_id" : "4",
        "_score" : 1.357075,
        "_source" : {
          "first_name" : "先森",
          "last_name" : "双口",
          "age" : 10,
          "about" : "散弹批发商",
          "interests" : [
            "嘿嘿",
            "游戏"
          ]
        }
      }
    ]
  }
}

这里查询到两个文档,一条是安的,一条是双口的。

但是我们发现两个文档中 _score 字段数字是不同的,_score 是Elasticsearch给查询出来的文档进行的相关性分析得出来的分数,这个分数越高说明匹配程度越高。我们搜索的是“散弹枪”,安的about中就含有“散弹枪”,但双口的about中包含的是“散弹”得分就比安低了。

我们有时候单纯的就只是想要搜索“散弹枪”这个词而不是“散”、“弹”、“枪”,这时候就要用到短语搜索了。

对 match 查询稍作调整,使用一个叫做 match_phrase 的查询,如下

GET /learn/user/_search
{
    "query" : {
        "match_phrase" : {
            "about" : "散弹枪"
        }
    }
}

结果

{
  "took" : 19,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 2.3385136,
    "hits" : [
      {
        "_index" : "learn",
        "_type" : "user",
        "_id" : "3",
        "_score" : 2.3385136,
        "_source" : {
          "first_name" : "倍",
          "last_name" : "安",
          "age" : 10,
          "about" : "散弹枪狂热者",
          "interests" : [
            "盗窃",
            "篮球"
          ]
        }
      }
    ]
  }
}

就只查询到含有“散弹枪”的文档了。

高亮搜索

许多应用都倾向于在每个搜索结果中 高亮 部分文本片段,以便让用户知道为何该文档符合查询条件。我们可以使用highlight 参数来实现,如下

GET /learn/user/_search
{
    "query" : {
        "match" : {
            "about" : "散弹枪"
        }
    },
    "highlight": {
        "fields" : {
            "about" : {}
        }
    }
}

结果

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 2.3385136,
    "hits" : [
      {
        "_index" : "learn",
        "_type" : "user",
        "_id" : "3",
        "_score" : 2.3385136,
        "_source" : {
          "first_name" : "倍",
          "last_name" : "安",
          "age" : 10,
          "about" : "散弹枪狂热者",
          "interests" : [
            "盗窃",
            "篮球"
          ]
        },
        "highlight" : {
          "about" : [
            "<em>散</em><em>弹</em><em>枪</em>狂热者"
          ]
        }
      },
      {
        "_index" : "learn",
        "_type" : "user",
        "_id" : "4",
        "_score" : 1.357075,
        "_source" : {
          "first_name" : "先森",
          "last_name" : "双口",
          "age" : 10,
          "about" : "散弹批发商",
          "interests" : [
            "嘿嘿",
            "游戏"
          ]
        },
        "highlight" : {
          "about" : [
            "<em>散</em><em>弹</em>批发商"
          ]
        }
      }
    ]
  }
}
几种重要的搜素
空搜索

简单的使用 _search ,不提供索引和类型,返回所有文档。

GET /_search
在搜索路径中使用通配符

gbus 索引中搜索所有的文档

/gb,us/_search

在任何以 g 或者 u 开头的索引中搜索所有的类型

/g*,u*/_search

检索所有索引下的usertweet类型的所有文档

/_all/user,tweet/_search
分页

主要是使用如下两个关键字。

size

显示应该返回的结果数量,默认是 10

from

显示应该跳过的初始结果数量,默认是 0

类似于关系型数据库中的Limit。

我们规定每页两条数据,则一到三页的数据可写为

GET /learn/user/_search?size=2
GET /learn/user/_search?size=2&from=2
GET /learn/user/_search?size=2&from=4

也可以写为请求体格式。如

GET /learn/user/_search
{
  "size": 2,
  "from": 2
}

执行过后我们发现他会出现不是按照id分页的,这就涉及到了排序问题。后面会讲到。

exists查询和missing查询

类似于SQL中的IS_NULL(missing)和NOT IS_NULL(exists)。

这种查询经常用于某个字段有值的情况和某个字段缺值的情况。

{
    "exists":   {
        "field":    "title"
    }
}
区间查询

range 查询找出那些落在指定区间内的数字或者时间:

{
    "range": {
        "age": {
            "gte":  20,
            "lt":   30
        }
    }
}

被允许的操作符如下:

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

如果要实现等于或不等于的操作需要将两个操作符联合使用。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
1月前
|
存储 Java API
Elasticsearch 7.8.0从入门到精通
这篇文章详细介绍了Elasticsearch 7.8.0的安装、核心概念(如正排索引和倒排索引)、RESTful风格、各种索引和文档操作、条件查询、聚合查询以及在Spring Boot中整合Elasticsearch的步骤和示例。
113 1
Elasticsearch 7.8.0从入门到精通
|
2月前
|
数据可视化 Java Windows
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
本文介绍了如何在Windows环境下安装Elasticsearch(ES)、Elasticsearch Head可视化插件和Kibana,以及如何配置ES的跨域问题,确保Kibana能够连接到ES集群,并提供了安装过程中可能遇到的问题及其解决方案。
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
|
2月前
|
存储 关系型数据库 MySQL
浅谈Elasticsearch的入门与实践
本文主要围绕ES核心特性:分布式存储特性和分析检索能力,介绍了概念、原理与实践案例,希望让读者快速理解ES的核心特性与应用场景。
|
20天前
|
缓存 架构师 数据库
后端开发的艺术:从入门到精通的旅程####
本文旨在探索后端开发的本质与魅力,通过一段段深入浅出的故事,串联起后端技术的精髓。不同于传统的技术总结,这里我们将以一位普通开发者的成长轨迹为线索,展现从初识编程到成为后端架构师的心路历程。每个阶段都伴随着挑战、学习与突破,最终揭示了技术背后的人文关怀与创新精神。 ####
|
10天前
|
监控 API 持续交付
后端开发中的微服务架构:从入门到精通
【10月更文挑战第26天】 在当今的软件开发领域,微服务架构已经成为了众多企业和开发者的首选。本文将深入探讨微服务架构的核心概念、优势以及实施过程中可能遇到的挑战。我们将从基础开始,逐步深入了解如何构建、部署和管理微服务。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和实用的建议。
22 0
|
1月前
|
JavaScript 前端开发
vue3教程,如何手动获取后端数据(入门到精通3,新人必学篇)
本文提供了一个Vue 3教程,讲解了如何使用axios库手动从后端获取数据,包括安装axios、配置后端访问地址、编写路由地址、发起HTTP请求以及在组件中读取和打印响应数据的步骤。
273 0
vue3教程,如何手动获取后端数据(入门到精通3,新人必学篇)
|
2月前
|
SQL JSON Java
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
本文为Spring Boot增删改查接口的小白入门教程,介绍了项目的构建、配置YML文件、代码编写(包括实体类、Mapper接口、Mapper.xml、Service和Controller)以及使用Postman进行接口测试的方法。同时提供了SQL代码和完整代码的下载链接。
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
|
1月前
|
Web App开发 JSON JavaScript
深入浅出:Node.js后端开发入门与实践
【10月更文挑战第4天】在这个数字信息爆炸的时代,了解如何构建一个高效、稳定的后端系统对于开发者来说至关重要。本文将引导你步入Node.js的世界,通过浅显易懂的语言和逐步深入的内容组织,让你不仅理解Node.js的基本概念,还能掌握如何使用它来构建一个简单的后端服务。从安装Node.js到实现一个“Hello World”程序,再到处理HTTP请求,文章将带你一步步走进Node.js的大门。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往后端开发新世界的大门。
|
2月前
|
前端开发 JavaScript Java
编程入门之前端和后端开发
前端开发就是开发网页上的内容展示与用户的交互,一部分后端开发工作就是开发数据访问服务,使前端可以通过后端服务对数据进行增删改查,也就是Crud,对前端用户的请求进行相应。
60 8
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
下一篇
无影云桌面