ElasticSearch的搜索及架构简单理解

200 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

ES搜索

es作为搜索引擎,最重要的就是搜索功能

es的搜索分为两种

  1. queries 全文检索
  2. aggregations 统计分析

全文检索是对数据进行查询,统计分析类似关系型数据库的sum,count等计算函数,这两种通常可以一起使用

1.1 全文检索

1.1.1 条件查询

GET twitter/_search?pretty
{
  "query": {
    "match": {
      "name": "zy"
    }
  }
}

带参数查询name=zy的文档

1.1.2 分页查询

{
    "query":{
        "match_all":{

        }
    },
    "from":"0",
    "size":"2"
}

from起始页码,size每页条数

1.1.3 过滤查询结果

{
    "query":{
        "match_all":{

        }
    },
    "from":"0",
    "size":"2",
    "_source":["name"]
}

查询结果中只有name属性,去除其他字段

1.1.4 排序

{
    "query":{
        "match_all":{

        }
    },
    "from":"0",
    "size":"2",
    "_source":["name"],
    "sort":{
        "age":{
            "order":"desc"
        }
    }
}

sort排序,根据某个字段升序降序排序,字段不能为text字段,否则报错

1.1.5 多条件查询及范围匹配

{
    "query":{
        "bool":{
            "should":[
                {
                    "match":{
                        "name":"zy"
                    }
                },
                {
                    "match":{
                        "age":"8"
                    }
                }
            ],
            "filter":{
                "range":{
                    "age":{
                        "gt":20
                    }
                }
            }
        }
    }
}

bool为多个条件,可以为should/must,should==or,must==and

filter过滤数据,增加范围匹配,gt大于关系

1.1.6 全文检索

{
    "query": {
        "match": {
            "name": "尧"
        }
    }
}

match关键字是全文检索,会把查询的关键词进行分词后,在匹配每个词项

match_phrase是把关键词分词后,匹配每个词项,还有位置,也可以理解为不分词匹配

1.1.7 高亮显示

{
    "query": {
        "match": {
            "name": "张李"
        }
    },
    "highlight":{
        "fields":{
            "name":{}
        }
    }
}

会对查询的结果进行关键字高亮显示,其实就是返回一个特殊的标记,如下

1.2 聚合查询

1.2.1 分组查询

{
    "aggs": {
        "count": { // 分桶桶名
            "terms": { // 操作类型
                "field": "age" //哪个字段
            }
        }
    },
    "size": 0 //不要原始数据
}

根据age分组,取数量

1.2.2 取平均值

{
    "aggs": {
        "avg": { // 桶名
            "avg": { // 取平均值
                "field": "age"
            }
        }
    },
    "size": 0
}

获取年龄的平均值

ES架构简单理解

es文档落盘

当写入数据时主要分为以下几步:

  1. 先写入lucene的index文件,es为全文检索做了优化,分段索引文件
  2. 将分段文件写入内存
  1. 记录写入日志,类似数据库的binlog,保证数据的安全
  2. 从内存写入操作系统文件缓冲区,写入缓冲区之后就可以进行查询了
  1. 从缓冲区进行落盘,写入磁盘

因为刷盘操作比较消耗io,所以刷盘操作一般可以间隔时间长一点(30min),但是refresh就要比较快,要达到类似实时的效果(1s)

es读取数据架构

读取数据:

  1. 客户端发送请求到协调节点
  2. 协调节点查询存在数据的所有分片和副本分片
  1. 采用轮询策略查询数据
  2. 返回客户端

es写入数据架构

与读取数据结构类似

  1. 客户端发送请求到协调节点
  2. 协调节点将存储的数据转换到对应的节点
    1. 这里的转换是根据公式计算数据应该存在哪个分片上===== hash(id)%主分片的数量 = 分片的位置
    2. 这也是为什么分片数不能修改的原因,分片数一旦改变,则数据位置就变化了
  1. 对应的主分片写入数据
  2. 副本写入数据
  1. 主分片反馈客户端