Elasticsearch基础

注:

  1. 该文档中对于API的调用都通过Kibana进行调用
  2. 该文档中 _doc 作为默认的类型

前置知识

  • 9300端口是Elasticsearch集群间组件通信端口,而9200端口是浏览器访问的HTTP协议的Restful端口
  • elasticsearch是面向文档的数据库,且一切都是JSON

Index 索引

        一个索引由一个名字来标识(必须全部是小写字母),并且当我们要对这个索引中的文档进行索引、搜索、更新和删除(CRUD)的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。

        Elastic 会索引所有字段,经过处理后写入一个反向索引(Inverted Index)。查找数据的时候,直接查找该索引。

        所以,Elastic 数据管理的顶层单位就叫做 Index(索引)。它是单个数据库的同义词。每个 Index (即数据库)的名字必须是小写。

下面的命令可以查看当前节点的所有 Index:

GET /_cat/indices?v

Elasticsearch 索引的精髓:一切设计都是为了提高搜索的性能

Document 文档

        在Index里面,单条记录(行)成为Document(文档),多个Document构成一个Index。

Document使用了JSON格式表示,如下:

{ "user": "张三", "title": "工程师", "desc": "数据库管理" }

        同一个 Index 里面的 Document,不要求有相同的结构(scheme),但是最好保持相同,这样有利于提高搜索效率。

Relational DB

ElasticSearch

数据库(database)

索引(indices)

表(tables)

types 会被弃用

行(rows)

documents

字段(columns)

fields

        elasticsearch(集群)中可以包含多个索引(数据库) ,每个索引中可以包含多个类型(表) ,每个类型下又包含多个文档(行) ,每个文档中又包含多个字段(列)。

映射 Mapping

        mapping 是数据处理的方式和规则方面做一些限制,如:某个字段的数据类型、默认值、分析器、是否被索引等等。这些都是映射里面可以设置的,其它就是处理 ES 里面数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。

Rest风格

基本规则

method

url地址

描述

PUT(创建,修改)

localhost:9200/索引名称/_doc/文档id

创建文档(指定文档id)

POST(创建)

localhost:9200/索引名称/_doc

创建文档(随机文档id)

POST(修改)

localhost:9200/索引名称/_update/文档id

修改文档

DELETE(删除)

localhost:9200/索引名称/_doc/文档id

删除文档

GET(查询)

localhost:9200/索引名称/_doc/文档id

查询文档通过文档ID

GET | POST(查询)

localhost:9200/索引名称/_search/文档id

查询所有数据

REST API:REST APIs | Elasticsearch Guide [7.5] | Elastic

查看Elasticsearch信息

GET _cat/indices
GET _cat/aliases
GET _cat/allocation
GET _cat/count
GET _cat/fielddata
GET _cat/health
GET _cat/indices
GET _cat/master
GET _cat/nodeattrs
GET _cat/nodes
GET _cat/pending_tasks
GET _cat/plugins
GET _cat/recovery
GET _cat/repositories
GET _cat/segments
GET _cat/shards
GET _cat/snapshots
GET _cat/tasks
GET _cat/templates
GET _cat/thread_pool

操作索引 Index

新建 PUT

直接项Elastic服务器发出 PUT 请求。如创建一个 weather 的 Index:

PUT /{索引名}
------------
PUT /weather

如果操作成功时,将会返回一个JSON对象,里面的 acknowledged 字段表示操作成功:

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

指定字段的类型

Elasticsearch中有着以下字段数据类型:

  • 字符串类型
    • text支持分词,全文检索,支持模糊、精确查询,不支持聚合,排序操作;text类型的最大支持的字符长度无限制,适合大字段存储;
    • keyword不进行分词,直接索引、支持模糊、支持精确匹配,支持聚合、排序操作。keyword类型的最大支持的长度为——32766个UTF-8类型的字符,可以通过设置 ignore_above 指定自持字符长度,超过给定长度后的数据将不被索引,无法通过term精确匹配检索返回结果。
  • 数值型
    • long、Integer、short、byte、double、float、half float、scaled float
  • 日期类型
    • date
  • 布尔类型
    • boolean
  • 二进制类型
    • binary
  • 等等…

创建 Index 时能够通过 mappings 指定文档字段的类型:

PUT /test 
{
  "mappings": {
    "properties": { # 表示字段集
      "name": { # 配置对应字段名称的类型
        "type": "text", # 配置类型
        "analyzer": "ik_max_word" # 指定分词器
      },
      "value": {
        "type": "long"
      }
    }
  }
}

追加字段

如果需要在已存在的文档中追加字段可以通过 PUT 来追加

PUT /account/_mapping
{
  "properties": {
    "gender": {
      "type": "long"
    }
  }
}

查看索引详情 GET

基于上面指定字段类型添加Index后,通过 GET 即可查看索引详情:

GET /{索引名}
------------
GET /test

查看索引映射信息

GET /account/_mapping

删除 DELETE

发送一个 DELETE 请求,即可删除指定 Index,如删除 weather:

DELETE /{索引名}
------------
DELETE /weather

** 操作文档 Document

新增 Document

有两种方式,分别是PUT和POST:

1、PUT

PUT /{索引名}/_doc/{文档 ID}
{ ... } # 字段
------------
PUT /test3/_doc/1
{
    "name": "何妨"
}

2、POST

POST /{索引名}/_doc
{ ... } # 字段
------------
POST /test3/_doc
{
    "name": "何妨"
}

相同点:

  • 在 Index 不存在时,都会创建对应的 Index

不同点:

  • PUT 需要指定文档 ID,而 POST 文档 ID 则是随机生成

更新文档 Document

存在两种方案,如:

1、PUT

  • version 会 +1
  • 直接替换文档所有值,如果有字段漏写,将会丢失该字段
PUT /{索引名}/_doc/{文档 ID}
{ ... } # 字段
------------

PUT /test3/_doc/1
{
  "name": "何妨",
  "age": 25
}

GET /test3/_doc/1

# 会对原数据直接覆盖,导致 age 字段丢失
PUT /test3/_doc/1
{
  "name": "何妨"
}
GET /test3/_doc/1

2、POST

  • 如果字段值和文档的值一样,则 version 不变
  • 注意需要写在 doc 属性里面
  • 只更新指定的字段
POST /{索引名}/_update/{文档 ID}
{ 
    "doc": {...} # 字段
} 
------------
PUT /test3/_doc/1
{
  "name": "何妨",
  "age": 25
}
GET /test3/_doc/1

# 只更新 age 字段
POST /test3/_update/1
{
  "doc": {
    "age": 18
  }
}
GET /test3/_doc/1

删除文档 DELETE

DELETE /{索引名}/_doc/{文档 ID}
------------
DELETE /test3/_doc/1

**** 文档查询

数据准备

PUT /account
{
  "mappings": {
    "properties": {
      "username": {
        "type": "keyword"
      }
    }
  }
}

PUT /account/_doc/1
{
  "name": "何妨",
  "username": "jayin",
  "password": "123456",
  "desc": "独自归去又何妨",
  "tags": ["程序员", "直男"]
}
PUT /account/_doc/2
{
  "name": "往事随风",
  "username": "wssuifeng",
  "password": "123456",
  "desc": "我吹过你吹过的晚风",
  "tags": ["大长腿", "暖男"]
}
PUT /account/_doc/3
{
  "name": "洪哥",
  "username": "chenghong",
  "password": "123456",
  "desc": "我是独一无二的",
  "tags": ["异次元", "小可爱"]
}
PUT /account/_doc/4
{
  "name": "何老师",
  "username": "jayin123",
  "password": "123456",
  "desc": "独自归去又何妨",
  "tags": ["程序员", "直男"]
}

简单查询

GET /{索引名}/_search?q={字段}:{值}
------------
GET /account/_search?q=name:何
GET /account/_search?q=username:jayin

注意:

  • 查询时如果对应字段类型为 text ,那么将会采用 分词匹配查询
  • 如果类型为 keyword,则不会使用分词匹配查询,而是全等查询

***** 复杂查询 query

*** match 分词匹配

match 会使用 分词器 进行分词解析

  • 默认查询
GET /account/_search
{
  "query": {
    "match": {
      "name": "何妨"
    }
  }
}
效果同  GET /account/_search?q=name:何妨

  •  多值匹配

如果需要匹配多个值时,可以用 ' ' 空格隔开

GET /account/_search
{
  "query": {
    "match": {
      "name": "何 风"
    }
  }
}

运行结果:

 

** match_phrase 整体匹配的模糊查询

match_phrase 匹配有以下规则:

  1. match_phrase也是采用分词
  2. 目标文档需要包含分词后的所有词
  3. 目标文档还要保持这些词的相对顺序和文档中的一致
GET /account/_search
{
  "query": {
    "match_phrase": {
      "desc": "吹过的晚"
    }
  }
}

运行结果:

        也就是说,match_phrase 严格要求 文档中的值分词后关键字的顺序 和 查询值中分词后的顺序相对一样

** term 精确查询

        term 不会对查询条件中的字段值进行分词操作,而是直接拿来与文档中对应字段进行全等匹配

但如果字段类型为 text 时,仍会被分词建立倒排索引,并通过倒排索引查找。适用于 number、date、keyword等查询,不适合 text

GET /account/_search
{
  "query": {
    "term": {
      "name": "何 "
    }
  }
}
-------------------
term 会把 '何 ' 看出一个整体进行查询,如果是match的话则会被分词器处理为 '何'

** terms 多值精确查询

GET /account/_search
{
  "query": {
    "terms": {
      "age": [
        "23",
        "24"
      ]
    }
  }
}
------------------- 功能同下
GET /account/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "age": 23
          }
        }, {
          "term": {
            "age": 24
          }
        }
      ]
    }
  }
}

运行结果:

 

**** fuzzy 模糊查询

GET /account/_search
{
  "query": {
    "fuzzy": {
      "name": {
        "value": "何妨",
        "fuzziness": 1
      }
    }
  }
}

查询结果:

 

该查询可以按编辑距离(fuzziness),进行匹配查询。如:

何妨 进行分词后:何妨
    如果是使用 match 查询时,只能够查询出 对应字段分词后包含“何妨”的文档
但在 fuzzy 中,则可以根据 编辑距离 进行查询,如将会查询:何妨、何、妨
    所以,在索引中对应字段分词后包含 上面 三种的都会查到

*** 全查询

查出所有文档

GET /account/_search
{
  "query": {
    "match_all": {}
  }
}
------------------ 同下
GET /account/_search
{}

*** _source 字段过滤

GET /account/_search
{
  "query": {
    "match": {
      "name": "何妨"
    }
  },
  "_source": ["name", "username", "desc"]
}

查询结果只列出在 _source 中指定的字段

 

** sort 排序

GET /account/_search
{
  "sort": [
    {
      "age": {
        "order": "desc"
      },
      "birth": {
        "order": "asc"
      }
    }
  ]
}
--------------------  上面那种优先级比较高
GET /account/_search
{
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    },
    {
      "birth": {
        "order": "asc"
      }
    }
  ]
}

注意,sort不支持对 text 和 keyword 进行排序

*** from、size 分页 (效率低下)

  • from:从第几条记录开始
  • size:查多少条

可以理解为 LIMIT {from}, {size}

GET /account/_search
{
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ], 
  "from": 2,
  "size": 1
}

*** bool 多条件查询

  • must:多条件查询,相当于 and,值是一个数组
GET /account/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "何妨"
          }
        }, {
          "match": {
            "username": "jayin"
          }
        }
      ]
    }
  }
}
---------------
WHERE name LIKE '%何妨%' AND username = 'jayin'

在 must 中的条件属于并列条件,所以 bool 里面的 must 属于多条件查询

  • should:满足其一即可,相当于 or ,值是数组
GET /account/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": "何妨"
          }
        }, {
          "match": {
            "username": "chenghong"
          }
        }
      ]
    }
  }
}
------------------
WHERE name LIKE '%何妨%' OR username = 'chenghong'

        should 属于 or 查询,满足其一即可匹配

  • must_not:等价于 must 的相反,也就是 ! 查询
  • filter:过滤,能够用于范围查询
    • gt:大于
    • lt:小于
    • gte / lte:包含等于
GET /account/_search
{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "age": {
            "gt": 23,
            "lt": 25
          }
        }
      }
    }
  }
}
----------------------
WHERE age > 23 AND age < 25

运行结果:

*** 高亮查询

通过 highlight 可以 设置哪些字段需要高亮,以及高亮标签

GET /account/_search
{
  "query": {
    "match": {
      "name": "何"
    }
  },
  "highlight": {
    "pre_tags": "<div class='active'>",  // 设置高亮前置标签
    "post_tags": "</div>", // 设置高亮后置标签
    "fields": {
      "name": {} // 标记出需要高亮的字段,这样只有该字段会被高亮处理
    }
  }
}

**** 聚合查询 aggs

** 分组统计 terms

GET /account/_search
{
  "aggs":{ //聚合操作
    "age_group":{ //名称,随意起名
      "terms":{ //分组
      	"field":"username" //分组字段
      }
    }
  }
}

运行后会统计相同用户名的数量,运行结果:

 可以看到查询结果中还附带了原始数据,如果不需要原始数据可以如下所示:

GET /account/_search
{
  "aggs":{
    "age_group":{
      "terms":{
      	"field":"username"
      }
    }
  },
  "size": 0 // 返回结果数量
}

** 平均值 avg

GET /account/_search 
{
  "aggs": {
    "age_avg": {
      "avg": {
        "field": "age"
      }
    }
  },
  "size": 0
}

除了上面两种外,还有:

  • max
  • min
  • sum
  • 等等...

分词分析

GET /_analyze 

{
    "text": "独自归去又何妨",
    "analyzer": "ik_max_word"
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值