一篇文章让你了解Elasticsearch搜索
一、索引1。1、常见概念
创建索引前,先弄清楚这几个概念,indextemplate、index、setting、mapping;alais、ilmpolicy;dynamictemplate、dynamicmapping。
es创建索引是相当灵活的,可以插入数据的时候,自动推断字段类型,生成索引【此时称为dynamicmapping】;也可以先创建索引【index】,再插入数据,不过这个索引是一对一;也可以创建一个索引模板【indextemplate】,后面生成索引直接使用索引模板创建,就不需要为每个索引设置字段类型了,但是索引模板字段类型固定,也会出现一定局限,这时还可以使用动态模板【dynamictemplate】做一些按条件生成索引。索引设置后,我们还可以为索引创建别名【alais】,这样当索引分片后(比如index1,index2),我们还可以通过一个统一名称去访问它,索引的数据存在冷、热、温不同的生命周期,我们可以通过设置索引的ilmpolicy去实现。1。2、字段类型
Elasticsearch字段类型类似于MySQL中的字段类型。Elasticsearch字段类型主要有:核心类型、复合类型、多字段特性、特殊类型。1。2。1、核心类型
核心类型可以划分为字符串类型、数字类型、日期类型、布尔类型、基于BASE64的二进制类型、范围类型
类型
具体类型
二进制类型
binary
字符串类型
text、keyword
布尔类型
boolean
数字类型
long、integer、short、byte、double、float、halffloat、scaledfloat
日期类型
date、datenanos
范围类型
range
字符串类型
Elasticsearch7。x有两种字符串类型:text和keyword,在Elasticsearch5。x之后string类型已经不再支持。text:text类型适用于需要被全文检索的字段,例如新闻正文、邮件内容等比较长的文字。text类型会被Lucene分词器(Analyzer)处理为一个个词项,并使用Lucene倒排索引存储。text字段不能被用于排序,无法模糊查询。keyword:keyword适合简短、结构化字符串,例如主机名、姓名、商品名称等,可以用于过滤、排序、聚合检索,也可以用于精确查询。
保存一个字符串新字段,可以自动识别为textkeyword类型,当我们不想分词查询时,可以name。keyword进行查询。如果想将已有的text不分词,可以执行上面命令,再name。keyword进行查询。
数字类型
数字类型分为long、integer、short、byte、double、float、halffloat、scaledfloat,其范围如下:long,263到2631integer,231到2311short,32768到32767byte,128到127double,IEEE754标准双精度浮点类型,8字节float,IEEE754标准单精度浮点类型,4字节halffloat,IEEE754标准半精度浮点类型,2字节scaledfloat,缩放类型浮点类型
数字类型的字段在满足需求的前提下应当尽量选择范围较小的数据类型,字段长度越短,搜索效率越高。
日期类型
在Elasticsearch中日期可以为以下形式:格式化的日期字符串,例如2019010100:00、20190101时间戳(和1970010100:00:00UTC的差值),单位毫秒或者秒
即使是格式化的日期字符串,Elasticsearch底层依然采用的是时间戳的形式存储。
布尔类型
JSON文档中同样存在布尔类型,不过JSON字符串类型也可以被Elasticsearch转换为布尔类型存储,前提是字符串的取值为true或者false。布尔类型常用于检索中的过滤条件。
二进制类型
二进制类型binary接受BASE64编码的字符串,默认store属性为false,并且不可以被搜索。
范围类型
范围类型可以用来表达一个数据的区间,可以分为5种:integerrange,可以表示最大的范围为〔231,2311〕floatrange,可以表达IEEE754单精度浮点数范围longrange,可以表示最大的范围为〔263,2631〕doublerange,可以表达IEEE754双精度浮点数范围daterange,可以表达64位时间戳(单位毫秒)范围1。2。2、复合类型
复合类型主要有array【数组】、object【对象】、nested【嵌套】。数组类型
Lucene底层并不真正支持数组类型,所以Elasticsearch也没有专用的数组类型,依据数组元素类型定,每个元素必须是同一种类型。例如:tag:〔1,2,3〕、〔a,b,c〕、〔{name:Trump},{name:Smith}〕是合法的。{mappings:{properties:{tag:{type:keyword}}}}Object类型
JSON字符串允许嵌套对象,一个文档可以嵌套多个、多层对象。可以通过object类型来存储二级文档,不过由于Lucene并没有内部对象的概念,Elasticsearch会将原JSON文档扁平化,例如文档:
{name:{first:Donald,last:Trump}}{name。first:Donald,name。last:Trump}【实际上ES会将其转换为以下格式,并通过Lucene存储】。nested类型【nested】
nested类型是特殊的对象类型,特殊的地方是索引对象数组方式不同,允许数组中的对象各自地进行索引【也是各个元素类型可以不一致】,目的是对象之间彼此独立被查询出来。{mappings:{properties:{actors:{type:nested,properties:{id:{type:keyword,store:true},name:{type:keyword,store:true},sex:{type:integer,store:true}}}}}}1。2。3、多字段特性
多字段特性(multifields),表示允许对同一字段采用不同的配置,比如分词、text。keyword等。
常见例子是对人名实现拼音搜索,只需要在人名中新增一个字段pinyin即可。
1。2。4、特殊类型
特殊类型:地理类型、ip(记录ip地址)、completion(实现自动补全)、tokencount(记录分词数)、murmur3(记录字符串hash值)。地理类型
地理类型分为两种:经纬度类型和地理区域类型,这里主要介绍经纬度类型:经纬度类型
经纬度类型自动可以存储经纬度相关信息。通过地理类型的字段,可以用来实现诸如查找在指定地理区域内相关的文档、距离某个点范围内的文档、根据地理位置修改搜索评分等需求。如果需要使用经纬度类型,需要手动定义映射。
{
mappings:{
properties:{
location:{
type:geopoint
}
}
}
}
geopoint(geopoint接受以下地理位置数据)
经纬度键值对,lat为纬度,lon为经度
{
location:{
lat:29。0,
lon:107。0
}
}
用逗号分割的字符串,前者为纬度,后者为经度
{
location:29。0,107。0
}
数组形式坐标
{
location:〔29。0,50。0〕
}
IP类型
可以用来存储IPv4或者IPV6地址,如果需要存储IP类型的字段,需要手动定义映射。
ip类型
PUTmyindex
{
mappings:{
properties:{
ipaddr:{
type:ip
}
}
}
}
PUTmyindexdoc1
{
ipaddr:192。168。1。1
}
GETmyindexsearch
{
query:{
term:{
ipaddr:192。168。0。016
}
}
}
iprange类型
PUTrangeindex
PUTrangeindexmapping
{
properties:{
ipwhitelist:{
type:iprange
}
}
}
PUTrangeindexdoc2
{
ipwhitelist:192。100。0。016
}
PUTrangeindexdoc3
{
ipwhitelist:192。100。100。024
}
GETrangeindexsearch
{
query:{
range:{
ipwhitelist:{
gte:192。100。0。0,
lte:192。100。88。0
}
}
}
}join类型
join类型是ES6。x引入的类型,以取代淘汰parent元字段。用来实现文档的一对一、一对多的关系。ES一般不用来做关系映射。
1。3、字段属性限制的是搜索、存储、聚合、排序等特性。
类型
说明
source
默认是打开的,将原始文档以JSON的形式存储在source字段中,在lucene中source只是一个字段,即在一个字段中存储了一个文档中所有字段的值。source是es层面的设置,相当于给lucene多加了一个字段用于存储整个原始文档的值。不需要读取原始字段内容可以考虑关闭,但是关闭后无法reindex,无法在查询中使用script。
enabled
默认值为true,设置字段是否索引分析。false仅存储,不做搜索和聚合分析。(只在source中存储,关闭index和docvalues操作)【不能查询、聚合,可以在source展示】
index
默认为true,控制当前字段是否索引,是否analyze,是否加入倒排索引,关闭后无法对其进行搜索【比如:手机号、身份证号等敏感信息,不希望被检索】但字段仍存储在source和docvalues,即字段可以被排序和聚合。【不能查询,可以聚合,在source展示】
indexoptions用于控制倒排索引记录的内容。
docs:只记录docid;freqs:记录docid和termfrequencies;positions:记录docid、termfrequencies和termposition;offsets:记录docid、termfrequencies、termposition和characteroffsets。
text类型默认配置为positions,其他默认为docs。
store默认是false,即为不存储该字段;如果该字段的store属性设置为true,则在lucene中该字段的值被单独存储,与source是相互独立的,同时开启会将该原始字段存储两份。【指定storedfields才能查询store字段】
docvalues
倒排索引可以提供全文检索的能力,但是无法对排序和聚合提供支持。docvalues本质是一个序列化的列式存储。这个结构非常适用于聚合,排序。es默认几乎为所有类型提供列docvalue支持。除了analyzed类型,而text字段就是analyzed类型,如果不需要对该字段排序或聚合。则关闭该字段的docvalue存储。
fielddata
默认值为false。实现聚合和排序,不过它是基于内存。
norms
默认值为true。是否需要对字段做打分操作。
dynamic
mapping级别的设置,控制字段的新增,true默认值,允许新增字段和写入;false不允许新增字段,文档可以写入,但是无法查询;strict文档不能写入。
coerce
默认是true。是否开启数据类型转换功能,比如数字类型字符串转数字。
multifields
多字段,灵活的使用多字段特性来解决多样的业务需求。
datedetection
默认是true。是否字段识别日期类型。
nullvalue
当字段遇到null值时的处理策略,默认为null,即空值,此时es会忽略该值。可以通过设定字段的默认值。
eagerglobalordinals
默认值为false。指明该字段是否加载全局序数?默认为false,不加载。对于经常用于术语聚合的字段,启用此功能是个好主意。
ignoreabove
默认值是256,该参数的意思是,当字段文本的长度大于指定值时,不会被索引【不能搜索】,但是会存储【可以随数据一起显示】。
1。4、mapping字段设置流程
1。4。1、字段是何种类型字符串类型需要分词则设定为text类型,否则设置为keyword类型。枚举类型基于性能考虑将其设定为keyword类型,即便该数据为整型。数值类型尽量选择贴近最大值的类型,比如byte即可表示所有数值时,即选用byte,节省空间。其他类型比如布尔类型、日期、地理位置数据等。1。4。2、是否需要检索完全不需要检索、排序、聚合分析的字段enabled设置为false(此字段值会出现在source中)不需要检索的字段index设置为false需要检索的字段indexoptions结合需要设定norms不需要归一化数据时关闭即可1。4。3、是否需要排序和聚合分析
不需要排序或者聚合分析功能docvalues设定为falsefielddata设定为false1。4。4、是否需要另行存储store设定为true,即可存储该字段的原始内容(与source中的不相关)一般情况是结合source的enabled设定为false时使用该属性
索引索引创建后,分片不能修改,副本数可修改。
二、搜索原理
Elasticsearch是分布式搜索引擎,因此提供的所有功能都是分布式的。默认情况下,ES的查询分为两个阶段,query阶段和fetch阶段。
query阶段
客户端发送一个search请求到Node3【任意节点】上,然后Node3会创建一个优先级队列,它的大小fromsize【假设:from90,size10】Node3转发这个search请求到索引里面每一个主shard或者副本shard上,每个shard会在本地查询然后添加100条结果到本地的排序好的优先级队列里面。每个shard返回docId和所有参与排序字段的值例如score到优先级队列里面,然后再返回10条给coordinating节点也就是Node3,然后Node3负责将所有shard里面的数据给合并到一个全局的排序的列表,再取10条。
fetch阶段
coordinating节点标识了那些document需要被拉取出来【合并后的10条】,并发送一个批量的mutilget请求到相关的shard上每个shard加载相关document,如果需要数据在当前shard,则当前shard将会返回数据到coordinating节点上一旦所有的document被拉取回来,coordinating节点将会返回结果集到客户端上
注意:当查询from90,size10时,即在每个分片都有一个优先级队列,都会查询100条,然后返回10条给协调节点,若有5个分片,协调节点就有50条数据,然后取10条。query阶段,每个shard只返回docId和所有参与排序字段的值例如score,在fetch阶段再通过docId查询source里数据返回客户端。查询过程分类queryandfetch(最快的)、querythenfetch(es默认的搜索方式)、DFSqueryandfetch(精确控制搜索打分)、DFSquerythenfetch(精确控制搜索打分和排名,最慢的)从性能考虑QUERYANDFETCH是最快的,DFSQUERYTHENFETCH是最慢的。从搜索的准确度来说,DFS要比非DFS的准确度更高。
三、搜索分类3。1、按结构分类3。1。1、URL
URI搜索方式通过URI参数来指定查询相关参数。GETalibabaemployeesearch?qlastname:Smith精确wherelastnamelikeSmithGETwebsitesearch?qname:tryingdate:2014wherenameliketryingordatelike2014,前缀表示必须与查询条件匹配GETsearch搜索所有的索引中所有的类型GETalibabasearch在alibaba索引中搜索所有的类型GETalibaba,kxtxsearch在alibaba和kxtx索引中中搜索所有的文档GETm,ksearch在任何以m或者k开头的索引中搜索所有的类型GETalibabaemployeesearch在alibaba索引中搜索employee类型GETgb,ususer,tweetsearch在gb和us索引中搜索user和tweet类型GETalluser,tweetsearch在所有的索引中搜索user和tweet类型{undefinedhits:{最重要的部分total:14,匹配到的文档总数hits:〔文档结果集{undefinedindex:us,type:tweet,id:7,score:1,它衡量了文档与查询的匹配程度,默认是按照score降序排列的source:{原始文档date:20140917,name:JohnSmith,tweet:TheQueryDSLisreallypowerfulandflexible,userid:2}},。。。9RESULTSREMOVED。。。〕,maxscore:1与查询所匹配文档的score的最大值},took:4,整个请求耗费了多少毫秒shards:{查询中参与分片的总数failed:0,正常情况下我们不希望分片失败,但是分片失败是可能发生的(遭遇到一种灾难级别的故障:丢失了相同分片的原始数据和副本)successful:10,total:10},timedout:false查询是否超时,默认情况下,搜索请求不会超时}
3。1。2、DSL
Requestbody搜索方式以JSON格式在请求体中定义查询query。
GETtwittersearch
{
query:{
term:{user:kimchy}
}
}3。2、按复杂度分类
注:包含URL和DSL,下面着重展示DSL。简单查询复合查询聚合查询
首层关键字
query
查询
aggs
聚合
sort排序。可以指定按一个或多个字段排序。也可通过score指定按评分值排序,doc按索引顺序排序。默认是按相关性评分从高到低排序。对于值是数组或多值的字段,也可进行排序,通过mode参数指定按多值的(minmaxsumavgmedian)。
GETbanksearch
{
query:{
matchall:{}
},
sort:〔
{
age:{
order:desc如果不给定,默认是asc,score默认是desc
}},
{
balance:{
order:asc
}},
score
〕
}
FromSize分页查询,请注意,FromSize不能超过index。maxresultwindow索引设置,默认值为10000。
在分布式系统中,对结果排序的成本随分页的深度成指数上升。这就是web搜索引擎对任何查询都不要返回超过1000个结果的原因:假设在一个有5个主分片的索引中搜索,size10(每一个分片产生前10的结果,返回给协调节点,协调节点对50个结果排序得到全部结果的前10个),size10from10000(每个分片不得不产生前10010个结果,然后协调节点对全部50050个结果排序最后丢弃掉这些结果中的50040个结果)。要解决它,请参阅scroll或searchafterapi以获得更有效的深度滚动方法。
GETsearch
{
from:0,size:10,
query:{term:{user:kimchy}}
}
SearchAfter在指定文档后取文档,可用于深度分页
searchafter的理念是,在不同分片上(假设有5个分片),先按照指定顺序排好,根据我们传的searchafter值,然后仅取这个值之后的size个文档。这5size个文档拿到Es内存中排序后,返回前size个文档即可
GETtwittersearch
{
size:10,
query:{
match:{
title:elasticsearch
}},
searchafter:〔1463538857,654323〕,
sort:〔
{date:asc},
{id:desc}
〕}
注意:使用searchafter,必须有全局唯一id来排序(最好排序中包含id字段)。取满足searchafter值的数据,再取size条数据。
Scroll与在传统数据库中使用光标的方式非常相似(游标查询允许我们先做查询初始化,然后再批量地拉取结果)。Scroll可以有效地执行大批量的文档查询,而又不用付出深度分页那种代价。它仅仅从还有结果的分片返回下一批结果。
游标查询会取某个时间点的快照数据,查询初始化之后索引上的任何变化会被它忽略。
深度分页的代价根源是结果集全局排序,如果去掉话查询结果的成本就会很低。游标查询用字段doc来排序。
GEToldindexsearch?scroll1m保持游标查询窗口一分钟
{
query:{matchall:{}},
sort:〔doc〕,doc是最有效的排序顺序
size:1000仅作用于单个分片,有可能取到超过这个值数量,
}
{返回结果
scroll:1m,
scrollid:cXVlcnlUaGVuRmV0Y2。。。
}
scrollid,每次请求会返回一个新值(它是一个base64编码的长字符),每次我们做下一次游标查询,我们必须把前一次查询返回的字段scrollid传递进去,当没有更多的结果返回的时候才算结束
source对返回的source字段进行选择
GETsearch
{或者source:obj。或者source:〔obj1。,obj2。〕
source:{
includes:〔obj1。,obj2。〕,
excludes:〔。description〕
},
query:{
term:{user:kimchy}
}
}
Fields指定返回哪些stored字段【没有stored字段,就不会返回】,可用来指定返回所有存储字段,不会返回source。
GETsearch
{
storedfields:〔user,postDate〕,
query:{
term:{user:kimchy}
}
}
ScriptFields
用脚本来对命中的每个文档的字段进行运算后返回
DocvalueFields返回存储了docValue的字段值,文档值是一种磁盘上的数据结构,以面向列的方式存储,这对于排序和聚合有效。
GETsearch
{
query:{
matchall:{}
},
docvaluefields:〔test1,test2〕
}
Postfilter后置过滤:在查询命中文档、完成聚合后,再对命中的文档进行过滤
{query:{
matchall:{}
},
postfilter:{先查询再过滤
term:{
price:30
}}}
还有一个对应的反向的操作,filtered(先过滤再查询,速度快),不过已废弃。filtered查询将替换为bool查询。
{query:{
filtered:{
query:{
match:{
matchall:{}
}},
filter:{
term:{
price:30
}}}}}
Highlighting
高亮显示
Explain对每次命中的分数计算方式启用解释
GETsearch
{
explain:true,
query:{
term:{user:kimchy}
}
}
Rescoring目前,rescoreAPI只有一个实现:rescorer查询,它使用查询来调整评分。在将来,可提供替代的再订阅者,例如,成对的再订阅者。rescorer查询仅对查询和后筛选阶段返回的topk结果执行第二个查询。每个分片上要检查的文档数可以由windowsize参数控制,该参数默认为10。默认情况下,原始查询和rescorer存储查询的分数是线性组合的,以生成每个文档的最终分数。原始查询和rescorer查询的相对重要性可以分别通过查询权重和rescorer查询权重来控制。两者都默认为1。
POSTsearch
{
query:{
match:{
message:{
operator:or,
query:thequickbrown
}
}
},
rescore:{
windowsize:50,
query:{
rescorequery:{
matchphrase:{
message:{
query:thequickbrown,
slop:2
}
}
},
queryweight:0。7,
rescorequeryweight:1。2
}
}
}
Preference
选择在那些分片上执行查询,它有primary、primaryfirst、replica。。
Version指定返回文档的版本字段
GETsearch
{
version:true,
query:{
term:{user:kimchy}
}
}
IndexBoost
允许在搜索多个索引时为每个索引配置不同的boostlevel。当来自一个索引的点击比来自另一个索引的点击更重要时(想想每个用户都有一个索引的社交图),这非常方便
minscore限制最低评分得分
GETsearch
{
minscore:0。5,
query:{
term:{user:kimchy}
}
}
NamedQueries每个过滤器和查询可以在其顶级定义中接受一个名称。
GETsearch
{
query:{
bool:{bool查询只对查询和过滤器有意义
should:〔
{match:{name。first:{query:shay,name:first}}},
{match:{name。last:{query:banon,name:last}}}
〕,
filter:{
terms:{
name。last:〔banon,kimchy〕,
name:test
}
}
}
}
}
Innerhits
父联接和嵌套功能允许返回在不同范围内具有匹配项的文档。
FieldCollapsing
用collapse指定根据某个字段对命中结果进行折叠3。2。1、基本查询Query查询和Filter查询
DSL查询分为:Query查询和Filter查询(查询(Query)和过滤(filter),查询即是之前得到的query查询,它(查询)默认会计算每个返回文档的得分,然后根据得分排序,而过滤(filter)直会筛选出符合的文档,并不计算得分,且它可以缓存文档,所以,单从性能考虑,过滤比查询更快)
Querycontext查询上下文,用在查询上下文中的子句回答这个文档有多匹配这个查询?。除了决定文档是否匹配,字句匹配的文档还会计算一个子句评分,来评定文档有多匹配。查询上下文由query元素表示。
查询器有:
matchall、match、multimatch、bool、wildcards、regexp、prefix、matchphrase
Filtercontext过滤上下文,过滤上下文由filter元素或bool中的mustnot表示。用在过滤上下文中的字句回答这个文档是否匹配这个查询?,过滤语句的目的就是缩小匹配的文档结果集,不参与相关性评分。被频繁使用的过滤器将被ES自动缓存,来提高查询性能。
过滤器有:
term、terms、range、exists、missing、bool、script、type、ids
3。2。2、复合查询复合查询模型:{query:{1、查询bool:{2、复合bool、boosting、constantscore、dismax、functionscoremust:〔3、复合关联词must、filter、should、mustnot{match:{4、简单查询关键字match、range、term。。。。title:Search5、查询的字段}},{match:{content:Elasticsearch}}〕,filter:〔过滤{term:{status:published}},{range:{publishdate:{gte:20150101}}}〕}}}
大类
子类
说明
bool
must
包含
filter
过滤
should
可能
mustnot
排除
boostingquery
positive用来区别must、mustnot组合中的mustnot粗暴过滤。positive包含,negative按照negativeboost分数降低结果顺序。
就是相近的不直接排除,而是排在后面。【查询苹果公司,苹果树排在后面】
{query:{boosting:{positive:{match:{content:apple}},negative:{match:{content:pie}},negativeboost:0。5}}}
negative
negativeboost
constantscore
filter
目的就是返回指定的score,一般都结合filter使用,因为filtercontext忽略score
dismax
queries只是取分数最高的那个query的分数而已。
GETsearch{query:{dismax:{queries:〔{term:{title:Quickpets}},{term:{body:Quickpets}}〕,tiebreaker:0。7}}}
functionscore
functionscore是处理分值计算过程的终极工具
3。2。3、聚合查询聚合查询模型{aggs:{查询类型trigger:{操作自定义名称datehistogram:{聚合类型【Metric、Bucketing】field:triggerTime,format:yyyyMMdd}}}}
分类
子类
关键字
含义
例子Metric(指标)它对文档进行权值计算,类似sql中的统计
单值分析
min
最小值
max
最大值
avg
平均值
sum
总数
cardinality
distinct聚合
多值分析
stats
min、max、sum、count、avg5个值一起输出
extendedstats
比stats多的维度:平方和、方差、标准差、平均值加减两个标准差的区间
percentile
百分比统计
percentilerank
百分比排名聚合
tophits
最高匹配权值聚合
geobounds
地理边界聚合
geocentroid
地理重心聚合
Bucketing(桶)它执行的是对文档分组的操作(与sql中的groupby类似)
terms
词聚合(字段分组groupby)
filter
过滤聚合
filters
多过滤聚合
range
范围分组聚合(按区间分组统计count)
daterange
日期范围聚合
iprange
【IPv4范围】的桶分聚合
missing
缺失值的桶聚合
Pipeline(管道)聚合基础上的聚合【从其他聚合而不是文档或字段获取输入的聚合。】包含bucketpath指定上一层的路径
parent父聚合
maxbucket、minbucket、avgbucket、thesumbucket
{size:0,
aggs:{
salespermonth:{
datehistogram:{
field:date,
interval:month
},
aggs:{
sales:{
sum:{
field:price
}}}},
avgmonthlysales:{
avgbucket:{
bucketspath:salespermonthsales
}}}}
stats、extendedstatusbucket、percentilesbucket
sibling兄弟聚合
derivative(求导)、cumulativesum(累计求和)、movingfunction(滑动窗口)
{aggs:{
salespermonth:{
datehistogram:{
field:date,
interval:month
},
aggs:{
sales:{
sum:{
field:price
}},
salesderiv:{对每个月销售总和sales求导
derivative:{
bucketspath:sales用于计算均值的权值路径,同级,直接用metric值
}}}}}}
Matrix(矩阵)
3。3、样例GET1400notificationlog202210search{size:1,返回条数query:{bool:{复合查询关键字must:〔{matchphrase:{简单查询viewType:10。117。58。88:80}},{range:{notificationTime:{gte:2022103100:00:00。000,lte:2022103123:59:59。999}}}〕}},aggs:{聚合查询关键字fenzu:{terms:{桶field:objectType}},distinctobjectTyp:{cardinality:{指标field:objectType}},callInterfaceTimeSlotrange:{【接口调用时间按照020,20100,100以上分组统计】range:{field:callInterfaceTimeSlot,ranges:〔{to:20},{from:20,to:100},{from:100}〕},aggs:{嵌套【对每个区间】bstats:{stats:{field:callInterfaceTimeSlot}}}},dataLengthstatictis:{datehistogram:{【抓拍接收时间,按小时分段统计】field:checkTime,interval:hour},aggs:{dataLengthsum:{sum:{【计算每个分段数据总大小】field:dataLength}}}},avgdataLength:{管道【父子】avgbucket:{bucketspath:dataLengthstatictisdataLengthsum【计算总大小】}}}}{took:10,timedout:false,shards:{total:5,successful:5,skipped:0,failed:0},hits:{total:{value:1266,relation:eq},maxscore:1。0020769,hits:〔〕,aggregations:{dataLengthstatictis:{buckets:〔{key:1667188800000,doccount:318,dataLengthsum:{value:603246。0}},{key:1667192400000,doccount:360,dataLengthsum:{value:682920。0}},{key:1667196000000,doccount:360,dataLengthsum:{value:682920。0}},{key:1667199600000,doccount:222,dataLengthsum:{value:421134。0}}〕},fenzu:{doccounterrorupperbound:0,sumotherdoccount:0,buckets:〔{key:12,doccount:1260},{key:3,doccount:6}〕},distinctobjectTyp:{value:2},callInterfaceTimeSlotrange:{buckets:〔{key:20。0,to:20。0,doccount:131,bmax:{count:131,min:14。0,max:19。0,avg:18。18320610687023,sum:2382。0}},{key:20。0100。0,from:20。0,to:100。0,doccount:1104,bmax:{count:1104,min:20。0,max:36。0,avg:22。08786231884058,sum:24385。0}},{key:100。0,from:100。0,doccount:25,bmax:{count:25,min:868。0,max:1213。0,avg:1049。44,sum:26236。0}}〕},avgdataLength:{value:597555。0}}}
四、数据处理4。1、script:ctx。source应用PUTpersontestdoc1{name:zhangsan,age:20,cards。sfz:12121,hairs:〔red〕,createTime:1666753812000}查询【字段修饰】GETpersontestsearch{scriptfields:{result:{script:{source:doc〔age〕。valueparams〔multiplier〕,params:{multiplier:2}}}}}结果:{index:persontest,type:doc,id:1,score:1。0,fields:{result:〔40〕}}内容更新【多字段更新、传参更新、判断更新、查询更新】传参更新POSTpersontestupdate1{script:{source:ctx。source。ageparams。count,lang:painless,params:{count:4}}}结果:age24数组添加元素POSTpersontestupdate1{script:{source:ctx。source。hairs。add(params。hair),lang:painless,params:{hair:blue}}}结果:hairsred、blue判断更新POSTpersontestupdate1{script:{source:if(ctx。source。hairs。contains(params。tag)){ctx。opdelete}else{ctx。opnone},lang:painless,params:{tag:blue}}}多字段更新【简写】POSTpersontestupdate1{script:ctx。source。age20;ctx。source。name程飞}匹配插入POSTpersontestupdatebyquery{script:{lang:painless,source:ctx。source。nameparams。par,params:{par:程飞}},upsert:{name:wangwu,age:30}}结果:插入新数据新增字段POSTpersontest6update{script:ctx。source。newfieldvalueofnewfield}结果{index:person,id:6,version:4,found:true,source:{name:zhangsan,age:24,cards。sfz:12121,hairs:〔red,blue〕,newfield:valueofnewfield}}删除字段POSTpersontestupdatebyquery{script:ctx。source。remove(cards。sfz),query:{bool:{must:〔{exists:{field:cards。sfz}}〕}}}结果:source中无cards。sfz字段4。2、分页
fromsizeGETteststudentnewsearch{query:{bool:{must:〔{match:{grade:初二}}〕}},sort:〔{id:{order:asc}}〕,from:0,size:3}searchafterGETteststudentnewsearch{query:{bool:{must:〔{match:{grade:初二}}〕}},sort:〔{id:{order:asc}}〕,size:2,searchafter:〔3〕}scrollPOSTteststudentnewsearch?scroll1m{size:2,query:{matchall:{}}}POSTsearchscroll{scroll:1m,scrollid:DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAxETQWdzZhZWdPWlFRQW1kRkpaQkxjNU9PUQ}4。3、排序
4。4、reindex当需要修改字段类型时,需要重新创建索引,并同步数据。1、创建新索引PUTstudenttestnew{mappings:{properties:{age:{type:long},bir:{type:date},bri:{type:date},grade:{type:text,fields:{keyword:{type:keyword,ignoreabove:256}}},id:{type:long},name:{type:text,fields:{keyword:{type:keyword,ignoreabove:256}}},nation:{type:text}}}}2、数据同步POSTreindex{source:{index:studenttest},dest:{index:studenttestnew}}4。5、rollover为索引添加alias是别名,别名绑定rollver,手动执行rollver满足条件后可以创建新索引【是执行rollver创建索引,不是插入数据】、【ilmpolicy自动执行默认是10分钟】。rollver滚动索引时,要求创建索引以数字结尾,最多6位,滚动时,会在数字上加1,默认是000001这6位数字。当我们在ILM中开启了rollover后,流转到下一节点的minage是在rollover触发后才开始计时的。当别名关联索引时【一对多】:通过索引【testxxxxxx】随时可以写数据。但是通过别名【testalais】,只有关联的索引【test000001】是iswriteindex,才能通过别名【testalais】插入数据。同一个索引【test】的滚动【test000001、test000002】,默认只有一个iswriteindex为true的索引【test000002】,就是别名【testalais】只能写到这个索引中【test000002】。当索引添加别名时【一对多】:当添加的别名【testalais1】设置了iswriteindex属性,原别名【testalais】会继续与索引关联,如果没有iswriteindex属性,原别名【testalais】就会与该索引解除关联,也就是通过原别名不能查询该索引的数据。创建模板【创建setting、mapping关联alais、ilm(rollover)】【templatealaisrolloverdata】PUTtemplatestudenttesttemplate{indexpatterns:studenttest,匹配索引的规则order:1,settings:{numberofshards:4,numberofreplicas:1,lifecycle:{name:studenttestilmpolicy,ilmrolloveralias:aliasstudenttestrolloveralias}},mappings:{properties:{name:{type:keyword},age:{type:long},birthday:{type:date,format:yyyyMMddHH:mm:ssyyyyMMddepochmillis}}},aliases:{aliasstudenttestrollover:{iswriteindex:true}}}ilm【自动rollover】设置ilm【自动滚动】PUTilmpolicystudenttestilmpolicy{policy:{phases:{hot:{minage:0ms,actions:{rollover:{maxage:30d,maxsize:100gb,maxdocs:3}}},delete:{minage:120d,actions:{delete:{}}}}}}添加数据【别名或者studenttest000001要包含后缀】POSTaliasstudenttestrolloverdoc5{name:zhangsan5,age:21,birthday:1666753812000}GETaliasstudenttestrolloversearchGETaliasstudenttestrolloveraliasGETilmpolicy手动rollover添加aliasesPUTstudenttest000001{aliases:{aliasstudenttestread:{iswriteindex:true}}}添加rollover【手动滚动,执行此句时,当满足条件就会创建新索引,创建索引是执行此触发的,插入数据,就会插入新索引】POSTaliasstudenttestreadrollover{conditions:{maxdocs:2,maxage:30d,maxsize:500gb}}POSTaliasstudenttestreaddoc12{name:lisi12,age:21,birthday:1666753812000}GETaliasstudenttestreadsearch