欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Elasticsearch 基本使用

程序员文章站 2022-07-05 12:30:56
...
原文链接:https://www.cpweb.top/1206

  以下内容基于Elasticsearch 7.10,使用Kibana进行交互,只演示一些基本操作,其它操作或者更复杂操作的请阅读官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html

一、基本概念

  在Elasticsearch中,一条数据就是一个文档(json格式)。每个文档都有与之关联的元数据,例如_index(文档所属的索引)、_type(文档的映射类型)和_id(文档编号)三个必须的元数据字段,当然在7.x版本中_type已经被弃用,它不在是创建索引时必须的了。
  可以说ES算是面向文档型的非关系型数据库,当然它本身也是排名前十最流行的数据库管理系统之一,目前排在第8(数据来源:https://db-engines.com/en/ranking)。
  最初,它们的结构:索引(index) ⇒ 类型(type) ⇒ 文档(docments) ⇒ 字段(fields),我们可以类比为关系型数据库:库 ⇒ 表 ⇒ 行 ⇒ 列。不过这并不是一个恰当的类比,但是为了帮助更好理解,我们先可以这样类比理解。在5.x版本中我们可以这样理解,6.x版本每个索引只允许使用一种类型,7.x版本中已经弃用。详细了解_type可以阅读:Elasticsearch 映射类型的变迁史

二、索引是什么

  Elasticsearch 索引指相互关联的文档集合。Elasticsearch 会以 JSON 文档的形式存储数据。每个文档都会在一组键(字段或属性的名称)和它们对应的值(字符串、数字、布尔值、日期、数值组、地理位置或其他类型的数据)之间建立联系。
  Elasticsearch 使用的是一种名为倒排索引的数据结构,这一结构的设计可以支持十分快速地进行全文搜索。倒排索引会列出在所有文档中出现的每个特有单词,并且可以找到包含每个单词的全部文档。通俗的来说倒排索引就是通过单词去找文档,像我们在购物网站上用各种条件筛选那就是,通过特定关键词去找包含关键词的商品。

三、创建索引

PUT /student

#获取索引信息
GET /student

在创建索引时,我们还可以指定索引设置、索引中字段的映射、索引别名。

1、设置分片和副本数量

分片和副本默认都为1。

PUT /my-index-1
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 2
  }
}

#获取索引设置
GET /my-index-1/_settings

#获取索引指定设置
GET /my-index-1/_settings/*shard*

2、字段映射

  在7.x之前,映射定义是包含在类型下,尽管现在不建议在请求中指定类型,但是如果需求,可以在请求中设置了参数include_type_name为true。

PUT /my-index-2
{
  "mappings": {
    "properties": {
      "name" : { "type" : "keyword" },
      "content": { "type": "text" },
      "date" : { "type" : "date" }
    }
  }
}

#获取索引映射
GET /my-index-2/_mappings

#获取索引指定字段映射
GET /my-index-2/_mapping/field/content
GET /my-index-2/_mapping/field/name,date
GET /my-index-2/_mapping/field/n*

3、索引别名

PUT /my-index-3
{
  "aliases": {
    "alias_1": { }
  }
}

#获取索引别名
GET /my-index-3/_alias

#通过别名获取索引信息(多个索引可以用一个别名)
GET /alias_1/_mapping

四、增

将JSON文档添加到指定索引中,如果文档已经存在,则请求将更新文档并增加其版本。
语法:

PUT /<target>/_doc/<_id>

POST /<target>/_doc/

1、自定义id

如果请求的索引不存在,将会自动创建该索引。

PUT /student/_doc/1
{
  "name" : "xm",
  "sex" : "male",  
  "age" : "18",
  "hobby": [
    "swimming",
    "basketball"
    ]
}

结果:

{
  "_index" : "student",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

2、随机id

对于随机id,我们需要使用POST,会为文档生成唯一的ID。

POST /student/_doc
{
  "name" : "xh",
  "sex" : "female",  
  "age" : "18",
  "hobby": [
    "swimming",
    "yoga"
    ]
}

结果:

{
  "_index" : "student",
  "_type" : "_doc",
  "_id" : "aTMmMnYBddrAqZGb1UsI",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

3、批量

  如果有很多要存入索引的文档,则可以使用 bulk API 批量提交。使用批量处理文档操作比单独一个个提交要快得多,因为它可以最大程度地减少网络往返次数。

POST _bulk
{ "index" : { "_index" : "test1", "_id" : "1" } }
{ "name" : "test1" }
{ "index" : { "_index" : "test2", "_id" : "1" } }
{ "name" : "test2" }

4、获取文档数据

#查询索引所有数据
GET student/_search

#查询索引指定id的数据
GET /student/_doc/1

#查询索引指定id的文档源数据(不含其它信息,只有源数据)
GET /student/_source/1

输出信息解释

#GET student/_search

{
  "took" : 0,               # 查询时长(以毫秒为单位)
  "timed_out" : false,      # 搜索请求是否超时  
  "_shards" : {             # 包含搜索了多少个分片,以及搜索成功、失败和跳过了多少个分片
    "total" : 1,            # 需要查询的分片总数
    "successful" : 1,       # 成功执行请求的分片数
    "skipped" : 0,          # 跳过请求的分片数
    "failed" : 0            # 未能执行请求的分片数
  },
  "hits" : {
    "total" : {
      "value" : 2,          # 找到了多少个匹配的文档
      "relation" : "eq"
    },
    "max_score" : 1.0,      # 找到相关文档的最大搜索评分
    "hits" : [              # 包含文档内容
    ......省略
    ]
  }
}

五、删

1、删除索引
DELETE /my-index-1

2、删除索引别名
DELETE /my-index-3/_alias/alias_1

3、删除索引指定文档
DELETE /student/_doc/1

4、通过查询删除
POST /student/_delete_by_query
{
  "query": {
    "match": {
      "name": "xh"
    }
  }
}

六、改

1、为文档建立一个索引用于测试
PUT /test/_doc/1
{
  "name" : "xm",
  "sex" : "male",
  "age" : "18"
}

2、更改name为xh
POST /test/_update/1
{
  "doc": {
    "name": "xh"
  }
}

3、增加一个hobby字段
POST /test/_update/1
{
  "doc": {
    "hobby": [
      "swimming",
      "yoga"
      ]
  }
}

4、通过查询进行更改
(1)将所有年龄为18的学生改成年龄为20
POST /test/_update_by_query
{
  "script": {
    "source": "ctx._source['age']='20'",
    "lang": "painless"
  }, 
  "query": { 
    "term": {
      "age": "20"
    }
  }
}

(2)将名字为xh的学生年龄改为18
POST /test/_update_by_query
{
  "script": {
    "source": "ctx._source['age']='20'",
    "lang": "painless"
  }, 
  "query": { 
    "term": {
      "name": "xh"
    }
  }
}

七、查

1、term和match

term搜索数据时为完全匹配不进行分词,适用于精确查询。match搜索时会进行分词。

GET /student/_search
{
  "query": {
    "term": {
      "name": "xm"
    }
  }
}

GET /student/_search
{
  "query": {
    "match": {
      "name": "xm"
    }
  }
}

我们可以实验下

PUT /tweet/_doc/1
{
  "content" : "hello world"
}
PUT /tweet/_doc/2
{
  "content" : "hello"
}
PUT /tweet/_doc/3
{
  "content" : "world"
}

分别用term和match搜索“content=hello”,再分别搜索“content=hello world”
当条件为“content=hello”:
    因为是单个单词,无论是term还是match,搜索结果为包含hello数据全部搜索出来。
当条件为“content=hello world”:
    term,执行无数据。match,三条数据全部出来了,即match将“hello world“,进行了拆分再检索匹配。

  对于拆分我们可以查询拆成了那几个单词,从结果来看拆分成了hello和world两个单词。即match会将“hello world”,拆分成了hello和world两个单词,然后再检索匹配这两个单词。那么意思就是从content字段中查询包含hello或者world的文档。

GET /tweet/_analyze
{
  "text" : "hello world"
}

如果只想匹配到“hello world”这条短语呢?这就要用到match_phrase,它用来匹配短语。

GET /tweet/_search
{
  "query": {
    "match_phrase": {
        "content" : "hello world"
    }
  }
}

2、bool查询

要实现更复杂的查询,可以使用bool查询来组合多个查询条件。
主要参数:

• must:文档必须全部满足这些查询条件。
• must_not:文档必须全部不满足这些查询条件。
• should:文档满足其中一个条件即可。
• filter:过滤搜索结果,文档必须都满足过滤条件才会展示出来。

3、must

查询年龄为18并且爱好为瑜伽的学生信息。

GET /student/_search
{
  "query": {
    "bool": {
      "must": [
        { "term": { "age": "18"}},
        { "term": { "hobby": "yoga"}}
      ]
    }
  }
}

4、must_not

查询性别不为女生并且爱好要有游泳的学生信息。

GET /student/_search
{
  "query": {
    "bool": {
      "must_not": [
        { "term": { "sex": "female" }}
      ],
      "must": [
        { "term": { "hobby": "swimming"}}
      ]
    }
  }
}

5、should

查询爱好为游泳或者瑜伽的学生信息。

GET /student/_search
{
  "query": {
    "bool": {
      "should": [
        { "term": { "hobby": "swimming"}},
        { "term": { "hobby": "yoga"}}
      ]
    }
  }
}

6、filter

查询爱好为swimming和yoga的学生信息。

GET /student/_search
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "hobby": "swimming" }},
        { "term": { "hobby": "yoga" }}
      ]
    }
  }
}
相关标签: ELK elasticsearch