以下内容基于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" }}
      ]
    }
  }
}

发表回复

验证码: 63 − 53 =