后端 --- 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可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
3月前
|
安全 Linux 开发工具
Elasticsearch 搜索入门技术之一
Elasticsearch 搜索入门技术之一
227 1
|
4月前
|
JSON 自然语言处理 数据库
数据库-ElasticSearch入门(索引、文档、查询)
数据库-ElasticSearch入门(索引、文档、查询)
288 0
|
2月前
|
SQL JSON API
ELK技术栈 - Elasticsearch 学习笔记(三)
ELK技术栈 - Elasticsearch 学习笔记(三)
39 0
|
2月前
|
存储 关系型数据库 MySQL
ElasticSearch 入门
【2月更文挑战第7天】ElasticSearch 入门 简介 ElasticSearch 的基本概念 ElasticSearch 的查询流程 ElasticSearch 的更新流程
37 2
|
2月前
|
存储 自然语言处理 搜索推荐
ElasticSearch入门篇
ElasticSearch入门篇
|
2月前
|
存储 JSON API
ELK技术栈 - Elasticsearch 学习笔记(二)
ELK技术栈 - Elasticsearch 学习笔记(二)
206 0
|
2月前
|
存储 SQL JSON
ELK技术栈 - Elasticsearch 学习笔记(一)
ELK技术栈 - Elasticsearch 学习笔记(一)
180 0
|
4月前
|
JSON 自然语言处理 开发工具
elasticsearch7.X学习笔记
elasticsearch7.X学习笔记
|
4月前
|
JSON 自然语言处理 负载均衡
数据库-Elasticsearch进阶学习笔记(集群、故障、扩容、简繁体、拼音等)
数据库-Elasticsearch进阶学习笔记(集群、故障、扩容、简繁体、拼音等)
56 0
|
4月前
|
自然语言处理 搜索推荐 算法
数据库-Elasticsearch进阶学习笔记(分片、映射、分词器、即时搜索、全文搜索等)
数据库-Elasticsearch进阶学习笔记(分片、映射、分词器、即时搜索、全文搜索等)
142 0