Elasticsearch 基础学习整理

基础概念

  • 节点 node:提供存储、索引和搜索功能的服务器。
  • 集群 cluster:多个节点的集合,共同持有全部数据。
  • 索引 index:拥有相似特征的文档的集合。
  • 类型 type:同一个索引中用于分类数据的一种方式,7.x之后的版本默认为单类型索引,类型固定为_doc
  • 文档 document: 可被索引的基础信息单元。
  • 分片和复制shards and replicas:将索引划分成多片存储在多个节点,解决单节点硬件限制的问题;而且可以为分片创建一份或多份拷贝,提高了部分节点失败情况下的高可用性。
  • 映射 mapping:定义了文档以及其字段如何被存储和索引。
  • 路由 routing:可选机制,用于分片之间分配文档。路由允许你控制文档应该被索引到哪个分片上,这可以用于优化查询性能、负载均衡和数据定位。默认情况下基础路由会通过哈希算法实现,以确保文档被均匀的分布在所有可用的分片上。

文档 API

新增文档记录

POST /<target>/_doc/<_id>
PUT|POST /<target>/_create/<_id>

  • _create_doc 的区别是,当文档已经存在时,后者会更新现有文档。
  • 可以不指定目标_id,会为文档创建唯一的 ID。
  • 可以通过 ?routing=<_routing>来指定路由分片。
  • 若指定的索引不存在,且设置了自动创建索引,则新增操作将会创建动态映射。可通过如下方法开启或关闭:
// PUT _cluster/settings
{
  "persistent": {
    "action.auto_create_index": "my-index-000001,index10,-index1*,+ind*"
  }
}

// PUT _cluster/settings
{
  "persistent": {
    "action.auto_create_index": "false"
  }
}

查询文档记录

GET|HEAD /<target>/_doc/<_id>
GET|HEAD /<target>/_source/<_id>

  • 使用_source返回的仅仅是文档数据
  • 可以通过?source=来控制返回的数据字段,如:
  • ?source=false 不显示文档数据
  • ?source=id,*.name 显示数据结构及层级控制
  • 也可以通过 ?_source_includes=_source_excludes来控制和过滤数据字段。

删除文档记录

  • DELETE /<target>/_doc/<_id> 直接删除
  • POST /<target>/_delete_by_query 按照查询删除

更新文档记录

POST /<target>/_update/<_id>

  • 更新记录操作不是完全替换,而是更新部分字段
  • doc:指定更新的内容
  • script:脚本字段,指定运行的脚本,此字段存在,则会忽略doc
  • script脚本可以通过ctx来访问_source_index_type_id_version_routing_now等字段
// POST test/_update/1
// 新增字段
{
  "doc": {
    "name": "new_name"
  }
}
{
    "script": "ctx._source.new_field=('new_field')"
}
// 通过参数更新字段
{
  "script" : {
    "source": "ctx._source.counter += params.count",
    "lang": "painless",
    "params" : {
      "count" : 4
    }
  }
}
  • script脚本可使用复杂结构体,也可直接传递简单语句
  • script脚本新增字段: ctx._source.new_field=('new_field')
  • script脚本删除字段: ctx._source.remove('new_field')
  • script脚本删除对象字段: ctx._source['my-object'].remove('my-subfield')"
  • upsert:当文档不存在时,将upsert内容作为新文档插入,存在则执行script
  • scripted_upsert:设置为true,则无论是否存在都会执行script
  • doc_as_upsert:使用doc内容作为upsert
  • POST /<target>/_update_by_query 按照查询进行批量更新

批量 API

POST /_bulk
POST /<target>/_bulk

  • 这些操作使用换行分割的 JSON(NDJSON)结构
  • 最后一行数据必须以换行符 \n 结束
  • Content-Type必须为application/jsonapplication/x-ndjson

复制索引

POST _reindex

{
  "source": {
    "index": "my-index-000001"
  },
  "dest": {
    "index": "my-new-index-000001"
  }
}

搜索 API

GET|POST /<target>/_search
GET|POST /_search

查询参数

  • from 文档偏移:默认 0
  • size 数量:默认 10
  • sort 排序:逗号分隔的<field>:<direction>列表
  • q 查询字符串语法
  • _source_source_excludes_source_includes:文档元控制字段,同之前解释。

请求体

  • 查询参数可以放入请求体
  • docvalue_fields 格式化:规定指定的字段按照指定的格式返回
  • query 查询语句
{
  "query": {
    "match": {
      "message": "this is a test"
    }
  }
}

Query SDLterm

精准匹配

  • term 可用于非text字段的精准匹配
  • term 针对text只能精准匹配一个单词
  • terms 用于一个字段包含多个值,类似于in
  • term 大小写敏感,默认分析器会将所有文本转换为小写,所以可能出现小写能查到而大写查询不到的问题
  • terms.keyword 针对text精准匹配完整字符串,被映射成keyword类型的会保留原始大小写,不会出现上面的情况。

Query SDLrange

范围查找

  • gte:大于或等于
  • gt:大于
  • lte:小于或等于
  • lt:小于
  • 针对日期类型,可以使用时间字符串now,如now/d表示当前时间,now-1d/d过去 24 小时

Query SDLmatch

高级查询,会根据查询字段类型的不一样,采用不同的查询方式

  • 查询字段是数值或日期,查询字符串会被转换
  • 查询内容若是不能分词的内容,则查询字符串不会被分词
  • 参数 query:查询的字符串
  • 参数 operator:多个搜索词之间的关系,默认OR
  • 参数 minimum_should_match:最低匹配数
  • 参数 boost:相关性因子,影响文档匹配的分值_score
{
  "query": {
    "match": {
      "message": {
        "query": "this is a test",
        "operator": "and",
        "minimum_should_match": 3
      }
    }
  }
}

Query SDLmatch_all

获取索引中的所有文档

{
  "query": {
    "match_all": {}
  }
}

Query SDLmulti_match

在多个字段上进行全文搜索

{
  "query": {
    "multi_match": {
      "query": "this is a test",
      "fields": ["title", "content", "*_name"]
    }
  }
}
  • 具有match的参数,还有一些额外参数
  • 参数 type:查询类型,值有以下:
  • best_fields 默认,综合考虑相关性
  • most_fields 根据每个字段的相关性
  • cross_fields 考虑跨字段的词
  • phrase 考虑词的顺序和位置

Query SDLmatch_phrase

用于精确匹配包含指定短语的文档,单词顺序与查询字符串中的单词顺序完全一致。

{
  "query": {
    "match_phrase": {
      "message": "this is a test"
    }
  }
}
  • 参数 query:查询的字符串
  • 参数 slop:定义词语可能存在的位置偏移量,设置为 1 意味着移动一个位置的字符串也能匹配。

Query SDLFilter

过滤器

  • 只针对查询结果进行过滤,但是不会考虑相关性得分
  • 过滤器可以被缓存
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "status": "active" } },
        { "range": { "age": { "gte": 30, "lte": 40 } } }
      ]
    }
  }
}

Query SDLBool

Bool Query(组合查询),可以组合多个查询条件
可以有多个查询子句,每个子句包含一组查询数组:

  • 子句must:必须满足
  • 子句filter:过滤器,不计算相关度
  • 子句should:满足 or
  • 子句must_not:必须不满足
  • 参数 minumum_should_matchshould子句应该满足的最小匹配数量
  • 参数 minumum_should_match:可以接收绝对数值、百分比和组合,比如 3<90%指匹配 3 个或 90%中最大的那个
  • 参数 boost:相关因子

聚合查询 aggs

给数据分组、提取数据。

  • size设置为 0,表示不需要原始文档,只关心聚合结果
  • query指定搜索条件
  • aggs 是聚合部分,是一个自定义聚名名称的对象,每个对象可配置分组参数
  • 参数field:指定分组字段
  • 参数size:指定返回条数
  • 参数order:指定排序,_count指数目,_key指分组的字段
{
    "size": 0,
    "query": {
        "match_all": {}
    },
    "aggs": {
        "user_post_nums": {
            "terms": {
                "field": "user_id",
                "size": 10,
                "order": {
                    "_count": "desc"
                }
            }
        }
    }
}

参考文档