本文已参与「新人创作礼」活动,一起开启掘金创作之路。
ES搜索
es作为搜索引擎,最重要的就是搜索功能
es的搜索分为两种
- queries 全文检索
- 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文档落盘
当写入数据时主要分为以下几步:
- 先写入lucene的index文件,es为全文检索做了优化,分段索引文件
- 将分段文件写入内存
- 记录写入日志,类似数据库的binlog,保证数据的安全
- 从内存写入操作系统文件缓冲区,写入缓冲区之后就可以进行查询了
- 从缓冲区进行落盘,写入磁盘
因为刷盘操作比较消耗io,所以刷盘操作一般可以间隔时间长一点(30min),但是refresh就要比较快,要达到类似实时的效果(1s)
es读取数据架构
读取数据:
- 客户端发送请求到协调节点
- 协调节点查询存在数据的所有分片和副本分片
- 采用轮询策略查询数据
- 返回客户端
es写入数据架构
与读取数据结构类似
- 客户端发送请求到协调节点
- 协调节点将存储的数据转换到对应的节点
-
- 这里的转换是根据公式计算数据应该存在哪个分片上===== hash(id)%主分片的数量 = 分片的位置
- 这也是为什么分片数不能修改的原因,分片数一旦改变,则数据位置就变化了
- 对应的主分片写入数据
- 副本写入数据
- 主分片反馈客户端