Bootstrap

es 3期 第12节-选择合适的数据查询方式

 #### 1.Elasticsearch是数据库,不是普通的Java应用程序,传统数据库需要的硬件资源同样需要,提升性能最有效的就是升级硬件。
#### 2.Elasticsearch是文档型数据库,不是关系型数据库,不具备严格的ACID事务特性,任何企图直接替代严格事务性场景的应用项目都会失败!!!

##### 索引字段与属性都属于静态设置,若后期变更历史数据需要重建索引才可生效
##### 对历史数据无效!!!!
##### 一定要重建索引!!!!

### GET 方式
# 最简单直接的查询,类似于key/value键值对插叙你,而却还是实时可靠的
# GET 查询基于逐渐ID查询,查询必须带有数据ID

## 单挑查询
# 必须具备主键ID,注意是es的doc id,而非lucene id
# 可查询元数据与源数据
# 也可以查询单纯的源数据
# GET /{index_name}/_doc/{id}
# GET /{index_name}/_source/{id}

DELETE device-001
PUT device-001/_doc/1
{
  "devName":"name-001",
  "devId":"001"
}
GET device-001/_doc/1
GET device-001/_source/1


## 多条查询
# GET /_mget,多条查询,Request body 参数中指定索引
# GET /{index_name}/_mget,多条查询Request Url参数中指定索引

DELETE device-001
PUT device-001/_doc/1
{
  "devName":"name-001",
  "devId":"001"
}
PUT device-001/_doc/2
{
  "devName":"name-002",
  "devId":"002"
}
# 查询方式1
GET /_mget
{
  "docs": [
    {
      "_index": "device-001",
      "_id": "1",
      "_source": true
    },
    {
      "_index": "device-001",
      "_id": "2",
      "_source": true
    }
  ]
}
# 查询方式2
GET device-001/_mget
{
  "docs": [
    {
      "_id": "1",
      "_source": true
    },
    {
      "_id": "2",
      "_source": true
    }
  ]
}
# 查询方式3
GET device-001/_mget
{
  "ids": [
    "1",
    "2"
  ]
}

## request 查询参数

# _source,是否返回原始数据,默认true,可指定多个字段,也可以设置false
GET device-001/_doc/1?_source=devId
GET device-001/_doc/1?_source=devId,devName
GET device-001/_doc/1?_source=false
# _source_includes,原始数据返回字段限制
GET device-001/_doc/1?_source_includes=devId
# _source_excludes,原始数据返回字段限制
GET device-001/_doc/1?_source_excludes=devId
# routing,分片路由字段
GET device-001/_doc/1?routing=1
# preference,分片选择,默认 RoundRobin 算法,可以选择_local有限本地,也可以选择自定义字符串
GET device-001/_doc/1?preference=RoundRobin
# refresh,查询之前,可以设定索引强制刷新,取值返回true/false,默认false
GET device-001/_doc/1?refresh=true
# version,数据版本,通过次设置,控制数据返回是否已经被覆盖
GET device-001/_doc/1?version=1
# version_type,数据版本类型,取值范围 internal、external、external_gte,默认internal
# stored_fields,原始数据存储在lucene中,字段属性store设置为true,默认fasse不启用
GET device-001/_doc/1?stored_fields=true
# realtime,数据是否试试返回,取值范围true|false,默认true
GET device-001/_doc/1?realtime=true

## 实时性检查
# refresh,设置时候立即刷新参数,是否影响GET实时查询
# refresh_interval,设置索引刷新时间,设置大一点
# realtime,实时性get查询参数设置,设置true/false,测试不同的数据

DELETE device-001
PUT device-001
{
  "settings":{
    "refresh_interval":"15s"
  }
}
PUT device-001/_doc/1
{
  "devName":"name-001",
  "devId":"001"
}
GET device-001/_search

### search 查询方式
# search 查询不是非实时的,且包括查询与返回2个阶段
# search查询是最常用的,基于以倒排索引为主实现,在同类多条件查询里面,效率是最高的
# 数值类查询基于BKD树算法,效率同比b-tree高不少

## search 语法
# GET/POST /{index_name}/ search,查询指定索引
# GET/POST /{index_name},{index_name}/ search,查询指定多个索引
# GET/POST/_search,查询所有所有

# 查询1,查询所有索引
GET _search
# 查询2,指定单索引
GET device-001/_search
GET kibana_sample_data_flights/_search
# 查询3,指定多索引
GET kibana_sample_data_flights,device-001/_search

## request 参数
# request_cache,是否启动查询缓存在结果为0时
# from,起始数据位置
# q,通过 URL输入查询条件
# size,单页大小
# sort,排序字段
# routing,查询路由控制
# batched_reduce_size,单分片返回数,默认512条就返回,无需等到全部查询完成
# pre_filter_shard_size,单分片过滤限制,默认 128
# _source,返回原始数据控制
# scroll,是否滚动快照查询
# search_type,全局打分还是分片打分,默认分片打分
# track_total_hits,是否返回总数量,7.0 之后默认返回 10000最多,与 6.X不兼容
# version,是否返回数据的版本号
# _source,指定返回数据字段
# _source_includes,指定返回数据字段
# _source excludes,指定排除返回数据字段
# seq_no_primary_term,设定是否返回主分片的任期编号,取值范围 true/false,默认 false

# max_concurrent_shard_requests,单分片查询并发度限制,默认5个
# preference,分片查询优先度,主分片与副本分片,包括本节点与其它节点,默认基于ES统计数据,此参数用于控制查询时,分片的路由选择,具体的可以参考最后参考文献连接
# 取值          说明                备注
# _only_local   仅限本节点上分片    与协调节点有关系
# _local        优先本地节点上分片,其次默认基于轮训算法选择指定固定节点上的分片
# _only nodes:<node-id>,<node-id>   指定固定的分片,分片编号
# _shards:<shard>,<shard>   自定义分片
# <custom-string>

# 查询1
GET kibana_sample_data_flights/_search?routing=1,2,3
{
  "track_total_hits":true
}
# 查询2
GET kibana_sample_data_flights/_search?version=true&track_total_hits=true&size=10&from=0&sort=FlightNum&_source_includes=FlightNum
{
  
}

## request body 参数
# es也支持提交参数在请求体里面,查询参数与url几乎一致

# 查询
GET kibana_sample_data_flights/_search
{
  "_source": [
    "FlightNum"
  ],
  "version": true,
  "track_total_hits": true,
  "from": 0,
  "size": 2,
  "sort": [
    {
      "FlightNum": {
        "order": "desc"
      }
    }
  ]
}

## response 响应参数
# took 耗时,请求到es后,es查询使用的时间,不是从客户端发出请求后的时间
# _shards,查询分片数信息,总分片数、成功分片数、失败分片数
# hits,返回的结果,返回数据总数,返回结果明细,依据查询条件有所不同

## 筛选数据字段
# ES数据索引字段存储有几个位置,可以分别从不同的位置获取,其中脚本功能是动态的组合
# _source 存储原始json数据
# docvalue_fields 存储倒排索引数据
# stored_fields
# script_fields 脚本生成数据
# runtime_mappings,运行时字段,详细见前面相关字段类型

GET kibana_sample_data_flights/_search
{
  "runtime_mappings": {},
  "docvalue_fields": ["FlightNum"],
  "stored_fields":["AvgTicketPrice"],
  "script_fields": {
    "MY_FIELD":{
      "script":{
        "source":"doc['OriginCountry'].value + '@' + doc['FlightNum'].value"
      }
    }
  },
  "version": true,
  "track_total_hits": true,
  "from": 0,
  "size": 100,
  "sort": [
    {
      "FlightNum": {
        "order": "desc"
      }
    }
  ]
}
GET kibana_sample_data_flights

## 查询任务操作
# 案例练习
# 取消查询任务

#查询任务检索 1
GET _tasks?actions=*search
#取消任务 1
POST _tasks/oTUltX4IQMOUUVeiohTt8A:12345/_cancel
#取消任务 2
POST _tasks/cancel?nodes=nodeldl,nodeld2&actions=*search

## DSL查询语言
# DSL领域查询语言
# 丰富的表达能力
# 学习难度高
# 需要持续联系
## DSL语言表达

# query
# 查询 1
GET kibana_sample_data_flights/_search
{
  "query": {
    "match_all": {}
  }
}
# 查询 2
GET kibana_sample_data_flights/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "FlightNum": {
              "value": "9HY9SWR"
            }
          }
        },
        {
          "match": {
            "DestWeather": "Rain"
          }
        }
      ]
    }
  }
}

## Query与 Filter 选择
# query,查询需要计算分值,分词场景下使用
# filter,查询无需计算分值,精确查询下使用
# query&filter,混合查询需要计算分值

# query 查询
GET kibana_sample_data_flights/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "DestCountry": {
              "value": "AT"
            }
          }
        }
      ]
    }
  }
}
# filter 2
GET kibana_sample_data_flights/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "FlightNum": {
              "value": "9HY9SWR"
            }
          }
        }
      ]
    }
  }
}
# 混合
GET kibana_sample_data_flights/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "DestCountry": {
              "value": "AT"
            }
          }
        }
      ],
      "filter": [
        {
          "term": {
            "OriginCityName": {
              "value": "Sydney"
            }
          }
        }
      ]
    }
  }
}

## 分值计算算法选择
# Elastic 分值计算算法默认提供3种,需要设置字段属性时设置指定,也可以自己定义分值计算方法函数
# BM25,默认算法,基于TF-IDF,做了归一化处理
# TF-IDF,词频-逆文本频率,ES目前已经停止支持
# Boolean,布尔计算方式,
# 自定义算法,自定义函数,此处省略..

DELETE device-001
PUT device-001
{
  "settings": {
    "refresh_interval": "15s",
    "number_of_shards": 1
  },
  "mappings": {
    "properties": {
      "devId": {
        "type": "keyword"
      },
      "devName00": {
        "type": "text"
      },
      "devName01": {
        "type": "text"
      },
      "devName02": {
        "type": "text",
        "similarity": "BM25"
      },
      "devName03": {
        "type": "text",
        "similarity": "boolean"
      }
    }
  }
}
GET device-001
PUT device-001/_doc/1
{
  "devId": "001",
  "devName00": "devName00",
  "devName01": "devName01",
  "devName02": "devName02",
  "devName03": "devName03"
}
GET device-001/_doc/1

## EQL 查询语言
# EQL,事件查询语言
# 擅长在基于时序类数据查询,必须包括至少2个字段,一个是时间序列字段,一个是事件类目
# 数据内容必须符合 ECS规范标准
# 应用在安全领域,日志领域;不能应用于业务系统领域
# 本次不详细展开,待需要时深入展开

## EQL 语言表达
# 查询语法
# GET/<INDEX-NAME>/_eql/search,指定索引名称
# 数据内容
# @timestamp ,必须包括时序的字段
# event.category,必须默认包括事件类目字段,如果没有,可以指定别的
 

# 安装 metricbeat采集本机日志
# 错误的案例 1
# 数据不符合 ECS 规范标准
GET /kibana_sample_data_ecommerce/_eql/search
{
  "query": """
  products where products.tax_amount==0
  """
}
# 错误的案例 2
# 数据不符合 ECS 规范标准
GET /kibana_sample_data_ecommerce/_eql/search
{
  "query": """
any where event.dataset=="sample ecommerce"
"""
}
# 正确的案例 1
# 数据符合 ECS 规范的
GET metricbeat-7.11.1/_eql/search
{
  "query": """
event where event.module=="system"
"""
}
# 正确的案例 2
# 数据符合 ECS 规范的
GET metricbeat-7.11.1/_eql/search
{
  "query": """
any where agent.type=="metricbeat"
"""
}

# GET 查询参数 https://www.elastic.co/guide/en/elasticsearch/reference/8.6/docs-get.html
# SEARCH 查询参数 https://www.elastic.co/guide/en/elasticsearch/reference/8.6/search-search.html
# 分片查询路由 https://www.elastic.co/guide/en/elasticsearch/reference/8.6/search-shard-routing.html
# EQL 查询语言 https://www.elastic.co/guide/en/elasticsearch/reference/8.6/eql.html
# ECS 参考规范 https://www.elastic.co/guide/en/ecs/1.8/index.html

;