Githubhttps://github.com/HealerJean

博客:http://blog.healerjean.com

一、属性介绍

索引库就类似数据库表,mapping 映射就类似表的结构,我们要向es 中存储数据,必须先创建“库”和“表”。

1、Mapping 映射属性

1)说明

a、type

type:字段数据类型,常见的简单类型有:

类型 说明
字符串 text(可分词的文本)
  keyword(精确值)keyword 类型只能整体搜索,不支持搜索部分内容
数值 long、integer、short、byte、double、float、
布尔: boolean
日期: date
对象: object

b、index

是否创建索引,默认为 true

c、analyzer

使用哪种分词器

d、properties

该字段的子字段

2)样例

{
    "age": 21,
    "weight": 52.1,
    "isMarried": false,
    "info": "真相只有一个!",
    "email": "zy@itcast.cn",
    "score": [99.1, 99.5, 98.9],
    "name": {
        "firstName": "柯",
        "lastName": "南"
    }
}
字段 说明
age 类型为 integer;参与搜索,因此需要index为true;无需分词器
weight 类型为float;参与搜索,因此需要index为true;无需分词器
isMarried 类型为boolean;参与搜索,因此需要index为true;无需分词器
info 类型为字符串,需要分词,因此是text;参与搜索,因此需要index为true;分词器可以用ik_smart
email 类型为字符串,但是不需要分词,因此是keyword;不参与搜索,因此需要index为false;无需分词器
score 虽然是数组,但是我们只看元素的类型,类型为float;参与搜索,因此需要index为true;无需分词器
name 类型为object,需要定义多个子属性
name.firstName 类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器
name.lastName 类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器

2、分词器

需要单独安装

问:分词器作用:

答案:创建倒排索引时对文档分词,用户搜索时,对输入的内容分词

问: IK 分词器有几种模式:

答案:ik_smart:智能切分,粗粒度;ik_max_word:最细切分,细粒度

二、索引库 CRUD

CRUD简单描述:

  • 创建索引库:PUT /索引库名
  • 查询索引库:GET /索引库名
  • 删除索引库:DELETE /索引库名
  • 修改索引库(添加字段):PUT /索引库名/_mapping

1、增 PUT

基本语法:

  • 请求方式:PUT
  • 请求路径:/索引库名,可以自定义
  • 请求参数:mapping 映射
PUT /es_log
{
    "mappings":{
    "properties": {
        "modifiedTime": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "nodeSortId": {
            "index": true,
            "store": true,
            "type": "integer"
        },
        "bizDesc": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "orderId": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "policyNo": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "inValidateTime": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "type": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "uuid": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "customCode": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "node": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "customType": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "insuranceId": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "createdTime": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "bizData": {
            "index": true,
            "store": true,
            "type": "keyword"
        },
        "traceSortId": {
            "index": true,
            "store": true,
            "type": "integer"
        }
    }
}
}

2、查 GET

基本语法

  • 请求方式:GET
  • 请求路径:/索引库名
  • 请求参数:无
GET /索引库名
{
  "es_log" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "bizData" : {
          "type" : "keyword",
          "store" : true
        },
        "bizDesc" : {
          "type" : "keyword",
          "store" : true
        },
        "createdTime" : {
          "type" : "keyword",
          "store" : true
        },
        "customCode" : {
          "type" : "keyword",
          "store" : true
        },
        "customType" : {
          "type" : "keyword",
          "store" : true
        },
        "inValidateTime" : {
          "type" : "keyword",
          "store" : true
        },
        "insuranceId" : {
          "type" : "keyword",
          "store" : true
        },
        "modifiedTime" : {
          "type" : "keyword",
          "store" : true
        },
        "node" : {
          "type" : "keyword",
          "store" : true
        },
        "nodeSortId" : {
          "type" : "integer",
          "store" : true
        },
        "orderId" : {
          "type" : "keyword",
          "store" : true
        },
        "policyNo" : {
          "type" : "keyword",
          "store" : true
        },
        "traceSortId" : {
          "type" : "integer",
          "store" : true
        },
        "type" : {
          "type" : "keyword",
          "store" : true
        },
        "uuid" : {
          "type" : "keyword",
          "store" : true
        }
      }
    },
    "settings" : {
      "index" : {
        "routing" : {
          "allocation" : {
            "include" : {
              "_tier_preference" : "data_content"
            }
          }
        },
        "number_of_shards" : "1",
        "provided_name" : "es_log",
        "creation_date" : "1714124877672",
        "number_of_replicas" : "1",
        "uuid" : "yhP-OiJ8RMOKs421Bqu2Dg",
        "version" : {
          "created" : "8020299"
        }
      }
    }
  }
}

3、修改索引库 PUT

说明:这里的修改是只能增加新的字段到 mapping 中。

倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改 mapping。虽然无法修改 mapping 中已有的字段,但是却允许添加新的字段mapping 中,因为不会对倒排索引产生影响。

PUT /索引库名/_mapping
{
  "properties": {
    "新字段名":{
      "type": "integer"
    }
  }
}

4、 删除索引库 DELETE

语法:

  • 请求方式:DELETE
  • 请求路径:/索引库名
  • 请求参数:无
DELETE /es_log

三、文档 CRUD

1、增 PUT POST

1)创建一个索引

第一个命令使用 PUT 方法创建名为 animal 的索引。在调用的末尾附加 pretty 命令,就可以打印友好 JSON 响应。

入参:

PUT /animal?pretty

出参:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "animal"
}

2)创建单个文档

1、animal 是文档的所在索引,_doc 是类型,1 是我们手工指定 id如果不指定,那就要用 POST 方法,ES 会为我们自动分配

入参

PUT /animal/_doc/1
{
  "name":"熊猫",
  "weight":"500kg",
  "zoo":"北京动物园"
}

出参:

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

3)创建多个文档

入参:

PUT /animal/_doc/1
{
  "name":"熊猫100",
  "weight":"500kg",
  "zoo":"北京动物园"
}
PUT /animal/_doc/2
{
  "name":"老虎100",
  "weight":"300kg",
  "zoo":"北京动物园"
}
PUT /animal/_doc/3
{
  "name":"狮子100",
  "weight":"500kg",
  "zoo":"上海动物园"
}
PUT /animal/_doc/4
{
  "name":"孔雀100",
  "weight":"100kg",
  "zoo":"南京动物园"
}
PUT /animal/_doc/5
{
  "name":"鳄鱼100",
  "weight":"400kg",
  "zoo":"河北动物园"
}

出参:

# PUT /animal/_doc/1
{
  "_index" : "animal",
  "_id" : "1",
  "_version" : 4,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 11,
  "_primary_term" : 1
}

# PUT /animal/_doc/2
{
  "_index" : "animal",
  "_id" : "2",
  "_version" : 3,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 12,
  "_primary_term" : 1
}

# PUT /animal/_doc/3
{
  "_index" : "animal",
  "_id" : "3",
  "_version" : 3,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 13,
  "_primary_term" : 1
}

# PUT /animal/_doc/4
{
  "_index" : "animal",
  "_id" : "4",
  "_version" : 3,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 14,
  "_primary_term" : 1
}

# PUT /animal/_doc/5
{
  "_index" : "animal",
  "_id" : "5",
  "_version" : 3,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 15,
  "_primary_term" : 1
}

2、查 GET

key 说明
_index 文档所属索引名称
_type 文档所属类型名
_id 文档唯一 ID
_score 文档相关性打分
_source 文档 JSON 数据
_version 文档版本信息

1)根据 Id 查询文档

入参:

GET /animal/_doc/1

出参:

	{
  "_index" : "animal",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "熊猫",
    "weight" : "500kg",
    "zoo" : "北京动物园"
  }
}

2)查询全部数据

入参:

GET animal/_search

出参:

{
  "took" : 66,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 5,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "animal",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "熊猫100",
          "weight" : "500kg",
          "zoo" : "北京动物园"
        }
      },
      {
        "_index" : "animal",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "老虎100",
          "weight" : "300kg",
          "zoo" : "北京动物园"
        }
      },
      {
        "_index" : "animal",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "name" : "狮子100",
          "weight" : "500kg",
          "zoo" : "上海动物园"
        }
      },
      {
        "_index" : "animal",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
          "name" : "孔雀100",
          "weight" : "100kg",
          "zoo" : "南京动物园"
        }
      },
      {
        "_index" : "animal",
        "_id" : "5",
        "_score" : 1.0,
        "_source" : {
          "name" : "鳄鱼100",
          "weight" : "400kg",
          "zoo" : "河北动物园"
        }
      }
    ]
  }
}

3)不指定字段查询

查询结果有很多记录,这是因为动物的名字里都带有 100

入参:

GET animal/_search
{
  "query":{
    "query_string":{
      "query":"100"
    }
  }
}

出参:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 5,
      "relation" : "eq"
    },
    "max_score" : 0.09844007,
    "hits" : [
      {
        "_index" : "animal",
        "_id" : "1",
        "_score" : 0.09844007,
        "_source" : {
          "name" : "熊猫100",
          "weight" : "500kg",
          "zoo" : "北京动物园"
        }
      },
      {
        "_index" : "animal",
        "_id" : "2",
        "_score" : 0.09844007,
        "_source" : {
          "name" : "老虎100",
          "weight" : "300kg",
          "zoo" : "北京动物园"
        }
      },
      {
        "_index" : "animal",
        "_id" : "3",
        "_score" : 0.09844007,
        "_source" : {
          "name" : "狮子100",
          "weight" : "500kg",
          "zoo" : "上海动物园"
        }
      },
      {
        "_index" : "animal",
        "_id" : "4",
        "_score" : 0.09844007,
        "_source" : {
          "name" : "孔雀100",
          "weight" : "100kg",
          "zoo" : "南京动物园"
        }
      },
      {
        "_index" : "animal",
        "_id" : "5",
        "_score" : 0.09844007,
        "_source" : {
          "name" : "鳄鱼100",
          "weight" : "400kg",
          "zoo" : "河北动物园"
        }
      }
    ]
  }
}

4)指定字段查询

入参:

GET animal/_search
{
  "query":{
    "query_string":{
      "query":"100kg",
      "fields": ["weight"]
    }
  }
}

出参:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.5198257,
    "hits" : [
      {
        "_index" : "animal",
        "_id" : "4",
        "_score" : 1.5198257,
        "_source" : {
          "name" : "孔雀100",
          "weight" : "100kg",
          "zoo" : "南京动物园"
        }
      }
    ]
  }
}

3、删 DELETE

1)删除文档

入参:

DELETE /animal/_doc/1

出参:

{
  "_index" : "animal",
  "_id" : "1",
  "_version" : 5,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 16,
  "_primary_term" : 1
}

4、更 PUT

Elasticsearch 提供近实时的数据操作和搜索功能。默认情况 下,从索引、更新、删除数据到在搜索结果中显示数据,会有少于1s 的延迟(刷新间隔)。这是与其他平台(如 SQL )的一个重要区别, 在 SQL 中,数据在事务完成后立即可用

1)覆盖文档

animal 是文档的所在索引,_doc 是类型,1 是我们手工指定 id如果不指定,那就要用 POST 方法,ES 会为我们自动分配

a、回顾创建单个文档

入参

PUT /animal/_doc/1
{
  "name":"熊猫",
  "weight":"500kg",
  "zoo":"北京动物园"
}

出参:

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

b、修改文档

ID1。如果用不同的(或相同的)文档再次执行上述命令,那么 Elasticsearch 将在现有文档的基础上替换(即重新索引)一个ID1 的新文档:

入参:

PUT /animal/_doc/1
{
  "name":"熊猫修改",
  "weight":"500kg",
  "zoo":"北京动物园"
}

2)更新文档 _update

Elasticsearch 除了能够索引和替换文档外,还可以更新文档。

Elasticsearch 实际上并不是进行就地更新,每当进行更新时, Elasticsearch 会删除旧文档,然后索引一个新文档,但这对用户来 说是一次调用。

⬤ 实际上 Elasticsearch 的数据存储结构决定了其不能 像关系数据库那样进行字段级的更新,所有的更新都是先删除旧文 档,再插入一条新文档,但这个过程对用户来说是透明的

a、修改文档

修改 Id1name

注意点:

⬤ 路径 _update

⬤ ` _doc ` 变成 doc

POST /animal/_update/1?pretty
{
    "doc": {
        "name": "熊猫update"
    }
}

b、修改文档并新增字段

POST /animal/_update/1?pretty
{
    "doc": {
        "name": "熊猫update",
        "age":10
    }
}

5、批量操作 _bulk

除了能够索引、更新和删除单个文档外,Elasticsearch 还提供 了使用批量API批量执行上述任何操作的功能。此功能非常重要,因 为它提供了一种非常有效的机制,可以以尽可能少的网络往返时间尽 可能快速地执行多个操作

1)注意事项

1、批量 API 不会由于其中一个操作失败而失败。如果一个操作由于 某个原因失败,它将继续处理后面的其余操作。当批量 API 返回时, 它将为每个操作提供一个状态(以相同的发送顺序),以便用户检查 特定操作是否失败。

2、对于删除操作,并不会立即删除对应的源文档,因为删除只需要删除文档的 ID。在 Elasticsearch 中,删除操作只是把需要删除的文档的 ID 记录到了一个列表中,当段合并时才有可能真正把源文档删除。

ContactAuthor