ElasticSearch
ElasticSearch+Logstash+Kibana
经典场景:
- 大规模集群日志收集分析系统
- 大规模订单数据离线文本搜索
- 分词查询
=========================
例子: 查询包含某个字的诗句
GET {
}
使用倒排索引: 这些被提取出来的的词叫term(词项)
put indexname/_doc/xxx?refresh&routing=key1 {abc:123,def:xxx} 索引一个文档, refresh表示立即落盘 , routing 指定自定义路由key(如果指定,那在删改查时也必须指定)
get indexname/_mapping 获取文档保存的结构(表结构)
字符串类型: text (此类字段会被分词,进入倒排索引), keyword(不会被分词),一个字段可以被多种类型索引(动态映射)
复杂的: 数组,对象, 嵌套
GEO,地理类型
元字段 meta-fields
put indexname/_mapping 可以自定义索引字段的类型
{
"properties":{
"name":{
"type":"text"
},
"age":{
"type":"integer"
},
"times":{
"type":"long"
#token_count 计数类型...上一层长度
}
}
}
索引的管理
静态设置
服务器分片等,备份数等
动态设置
post /suoyin/_open(_close) 打开/关闭索引(用于释放内存资源, 要使用的时候再打开)
get /_cat 获取ES服务的各种数据
get /_cat/indices?v 获取当前服务器概览
get _settings 获取当前机器上所有索引配置
get /suoyin/_settings 获取指定索引的配置
put /suoyin/_settings 设置指定索引的配置
{
"配置项" : 值
}
文档的管理
put /suoyin/_doc/1(id,如果不设置将生成guid) 索引一个文档,再次执行覆盖之前数据
{
"aaa":123,
"bbb":456,
...
}
post /suoyin/_update/1 更新文档的字段,如果不存在,则新增
{
"doc": { --如果文档不存在则报错
"bbb":789
},
"upsert":{ --如果文档存在则新增字段, 如果文档不存在则创建文档
"ccc":6546,
"ddd":6545644
},
"doc_as_upsert":true --如果文档不存在, 则使用doc中的字段创建文档
}
delete /suoyin/_doc/1 删除文档
数据检索和分析 _search 接口, DSL–>ES的查询语言
get /suoyin/_search
{
"query" :{ ----各种查询子句
"match_all":{}, 查询所有数据
===========================以下搜索项为基于词项的精确检索
"term":{ 基于词项,精确匹配查询 1=1
"aaa": 123123
},
"terms":{ #类似于in,但是比in厉害,可以与数组字段取交集不为空的结果
"bbb":["111","222"]
},
"terms":{ #可以跨索引查询,以其他索引的结果为条件进行新的查询,类似于join
"cccc":{
"index": "其他索引",
"id":123,
"path":"其他索引的字段"
}
},
"range":{ #范围查询
"eeee":{
"gte": 100, 大于等于
"lte": 200, 小于等于
"gt": 12, 大于
"lt": 113, 小于
"booste": 相关性评分
}
},
"exists":{ #指定字段内容是否存在
"field":"aaa"
},
"prefix":{ 以"abc"为前缀的结果
"eeesdf":"abc"
},
"wildcard":{ 通配符查询,避免通配符出现在条件开头, 开销太大
*匹配任何字符
?匹配单个字符
},
"regexp":{ 正则查询
},
},
"size":5 返回文档的数量
"from":1 与size配合使用,用于分页
#(from+size)最大不可超过index.max_result_window(此值可改)
#例如,从10000条开始取20条,ES会把10020条数据全取出来,然后截取后20条
#搜索引擎认为人们通常只会取前几页结果查看,几乎不会翻到最后去...
"_source":["aaa","bbb","aa*","*bb"], 只取指定字段,支持通配符
"_source":{
"include":["*aaa","*bbb"], 指定包含字段
"exclude":["aa*","bb*"] 指定排除字段
},
"sort":[{"字段名":"asc"},{"字段名":"desc"}] 排序
}
全文检索分析
分析文本–>
字符过滤器–> 可以纠正一些字符,替换特殊字符等…
char_filter
默认的有: html_strip html字符过滤器,
mapping 映射字符过滤器(键值对配置映射),
pattern_replace 正则替换过滤器
切分分词器–> 需要指定分词器, 默认使用内置标准分词器,只能使用一个
发生在:1 .索引文档时, 2.搜索时
tokenizer:(分词器)
1) standard, 标准分词器
2) keyword, 关键词分词器,不分词,因为分词器必须指定,不想分词时用这个
3) letter 字母分词器
4) lower 小写分词器(字母分词器+小写分词过滤器)
5) white 空白分词器
6) 模式分词器(正则)
7) UAX,url电子邮件分词器 (会保留电子邮件地址)
8) 路径层次分词器 按照路径来分
9) …还有很多…去官网查吧…
停止词/停用词: 常用的词对于分析没什么用处 例如: i ,the , is , this , what
分词过滤器->允许有多个分词过滤器, 停止词过滤器, 小写过滤器等等等…
token_filter
标准分词过滤器(啥事也不做, 占位用)
小写分词过滤器 大写转换为小写
长度分词过滤器 保留指定长度范围的关键词
停用词分词过滤器 剔除停用词
截断分词过滤器
…还有很多…去官网查吧
内置分析器
standard (默认标准分析器) -->0个字符过滤器, 标准分词器,小写分词过滤器,停用词分词过滤器
get _analyze 查看文本分词方式
get /suoyin/_analyze
索引文档时:
- 查看字段上是否设置了分词器
- 查看索引上是否设置了分词器
- 使用全局默认分词器(标准分词器)
使用搜索请求时:
1.搜索请求自带声明
2.字段上的search_analyzer
3.字段上的analyzer
4.索引上默认的default_search 指定分词器
5.全局默认的standard
#为索引设置分析器
put /suoyin/123{
"settings":{
"analysis":{
"analyzer":{
"default":{配置索引默认分析器
"type":"simple"
},
"default_search":{ 配置默认搜索分析器
"type":'whitespace'
}
"自定义analyzer":{ 配置索引自定义分析器
"type":"standard",
"stopword":["the","bnbb"]
},
"mappingAnalyzer":{ 配置一个映射类型的分析器
"tokenizer":"keyword",
"char_filter":["my_chars"] 可以写多个
},
"regexpAnalyzer":{ 配置一个正则表达式的分析器
"tokenizer":"keyword",
"char_filter":["reg_chars"]
},
"aaaaAnalyzer":{
"tokenizer":"",
"filter":"",
"char_filter":"",
"type":"custom"
}
},
"char_filter":{
"my_chars":{
"type":"mapping",
"mappings":["aaa=>123","haha=>fuck"]
},
"reg_chars":{
"type":"pattern_replace",
"pattern":"xxxxsss",
"replacement":"替换后的文字"
}
}
}
}
}
##指定索引某个字段的分析器
put /suoyin
{
"mappings":{
"properties":{
"abcsdf":{
"type":"text",
"analyzer":"standard", 索引时的分析器
"search_analyzer":"simple" 查询时的分析器
}
}
}
}
post /索引/_analyze 查看分词器分词结果
{
"field":"aaab",
"text":"内容"
}
post _analyze{ 使用html字符过滤器来去除html字符
"tokenizer":"keyword", 分词器名称
"char_filter":["html_strip"],
"text":"<p>sdfasd hahahahah >"
}
映射字符过滤器
指定分析器来做分词查询
post /suoyin/_search{
"query":{
"match":{
"aaabbb":{
"analyzer":"分析器名"
}
}
}
}
安装ES插件
cd /es_home/bin/elasticksearch-plugin install 插件地址
常用的中文分词器:
ik_max_word 拆的很细,按照中文语义拆的越细越好
ik_smart 拆的粒度比较大
全文查询
get /suoyin/_search
{
"query":{
"match":{
"elk":"aaa bbb ccc", 包含词项,
"operator":" and ", 操作符-->默认是or
},
"match":{
"字段名":{
"elk":"aaa bbb ccc", 包含词项,
"operator":" or ", 操作符
"minimum_should_match":2 至少包含词项的个数
}
},
"multi_match":{ 查多个字段
"query":"查询内容", 多个字段出现这个内容
"fields":["aaa","bbbb"]
},
"match_phrase":{ 包含以下短语, 并且顺序一样
"字段名":" aaa bbb ccc",
"slop":0 词项相差多远之内.依然被视为匹配
},
"match_phrase_prefix":{ 包含以下短语, 并且顺序一样,把词项最后一个做为前缀进行搜索,前缀搜索,开销更大
"字段名":" aaa bbb ccc",
"slop":0, 词项相差多远之内.依然被视为匹配
"max_expansions":50 默认, 前缀搜索的最大匹配数
},
模糊查询,比sql的like更厉害, 可以纠错提示,错误纠正-->使用了"编辑距离"算法
"fuzzy":{
"字段名":"aaabbb",
"fuzziness":1 编辑距离, 默认是auto , 可选值是 0,1,2,auto
}
},
"suggest":{ 提示建议器
"msg-suggest":{
"text":"aaaa bbbbb cccc", 查询词项
"prefix": "aa", 查询内容前缀
"term":{ term 提示器 ,把单独词项拆出来,每个做提示
"字段":"aaa"
},
"phrase":{ phrase提示器, 短语提示
"字段":"aaa"
},
"completion":{ 自动补全提示器, 文档索引时需要指明字段权重
"字段":"aaa"
}
}
}
}
编辑距离算法: Levenshtein, NGram
Levenshtein–>用于在单个词的模糊查询
替换, 插入, 删除
从一个词变成另一个词要操作的次数,就叫编辑距离
fireFix -->fireFox 距离为1
ear—>earth 距离为2
NGram–>用于多个单词组成的文本
把单词两两拆分,
firefix:fi ir re ef fi ix 6
firefox:fi ir re ef fo ox 6
6+6-2X4=4 —>编辑距离
A+B-2*(交集数)
组合查询
bool 布尔查询,结果必须满足子句条件–>子句影响相关度
bool查询包含以下子句
must 结果必须包含的子句中的内容-->影响相关度
should 不影响返回的结果, 但影响相关度, 如果查询条件中只有should,则影响结果
filter 对查询出的结果再进行一次过滤,必须包含的内容,不影响相关度
must_not 不能包含的内容, 不影响相关度
dis_max 查询,分离最大化查询将任何与任一查询匹配的文档作为结果返回,但只将最佳匹配的评分作为查询的评分结果返回
使用 "queries" 数组来接收多个查询条件 match ... term 等
"tie_break" 属性: 影响
constant_score 查询 对查询返回结果中的所有内容,指定相关度评分
用法与bool差不多, 加参数"boost",对返回值指定评分, 用于子查询再组合,
影响子查询相关度在总查询中的权重 --->嵌套查询下有用
boosting 查询 可用于查询降权
positive 类似于bool中的must , 结果必须满足该条件
negative 类似于bool中的must_not 拉低结果的评分相关度,但仍会返回结果
nagetive_boost 指定nagetive条件结果的相关度系数, 最终结果评分需要乘上该值
function_score 查询 提供了打分函数, 对查询出来的文档进行分析
1.field_value_factor
2.衰减函数: gauss , exp , lin
{
"query":{
"function_score":{
"query":{
"query_string":{
"fields":["aaa"."bbbbb"],
"query":"(key1) OR (key2)"
},
"functions":[
{"weight":2},
{"random_score":{}}
],
"score_mode":"max", #sum min
"boost_mode":"avg",
"field_value_factor":{ #添加某个列作为影响因子
"field":"aaa",
"factor":0.001,
"modifier":"reciprocal", #取倒数
-->还有很多运算方式
"missing":1000 #如果字段没有值, 设置默认值
}
}
}
}
}
单条件下的相关度查询
type: "best_fields"."phrase","phrase_prefix" --->与组合查询中的dis_max查询几乎一样
"most_fields" --->指定多个字段查询时, 字段匹配的越多,评分越高, 与组合查询中bool的should相似
"cross_fields" --->多字段情况下, 把多个字段内容合并后再查询...
Aggregation 聚合查询 类型比较多
post /suoyin/_search?filter_path=Aggregations #只显示聚合结果
{
"query":{} ...一些查询条件
"aggs":{
"<聚合名称>":{
"<聚合类型>":{
<聚合体>
}
},
aggs:{ #聚合嵌套,子聚合是在父聚合数据的基础上再做运算
}
},
}
指标聚合
percentile
范围分桶聚合
**数值范围**,自定义范围
range
date_range
ip_range
**间隔范围**固定间隔
histogram 数值间隔
date_histogram 日期间隔
auto_date_histogram
词项字符串分桶
terms 展示词项数量
sampler 从分片中取多少条样本用于下面的查询,样本数不同会影响到查询结果
sigificant_terms 前景集() 背景集(词项全集)
sigificant_text
cardinality 统计不重复词项数量
单桶聚合
filter(s)聚集,定义一个过滤器, 满足条件的放入分桶
global聚集 所有文档归入一个桶,忽略query查询条件
missing聚集 把某个字段缺失的文档归入一个桶中
composite聚集 把不同类型的聚集结果组合成笛卡尔积
管道聚合 ,以相关聚集结果为基础,再聚合
buckets_path: 聚集的名称>指标值.分隔符
基于兄弟聚集
基于父级聚集 , 含滑动窗口聚集(moving_fn)
单桶聚集 bucket_script,bucket_selector,bucket_sort
父子关系查询
has_child 通过子文档找父文档
has_parent 通过父文档找子文档
ES中保存对象时会把对象平铺开–>nested 嵌套类型使用,将每个对象单独建一个文档(隐藏式)
{aaa:111,bbb:{ccc:222,ddd:333}}
会保存成
{
aaa:111,
bbb.ccc:222,
bbb.ddd:333
}
这样在查询时会导致一些问题,需要在mappings里把相应嵌套对象声明为**nested**类型才不会平铺开
nest 聚集
nest_reverse
使用SQL 来查询数据
post _sql?format=json,txt,csv.. 还有其他类型
{
"query":""select 字段1,字段2 from doc名 where 条件 order by 字段 desc"",
"fetch_size":10 取多少条,如果取下一页的话,需要通过上一次返回值中的游标参数去请求
}
post _sql?format=json
{
"cursor":"上一次请求的游标"
}
//查询完毕必须关闭游标释放资源
post _sql/close
{
"cursor":"未关闭的游标"
}
支持的语句: select , show , describe(查看索引基础信息)
show functions 显示支持的sql方法
show tables 显示当前存在的索引
show columns in 索引名 查看索引列