中國(guó)的網(wǎng)站域名新媒體營(yíng)銷案例分析
腳本查詢
-
概念
Scripting是Elasticsearch支持的一種專門用于復(fù)雜場(chǎng)景下支持自定義編程的強(qiáng)大的腳本功能,ES支持多種腳本語(yǔ)言,如painless,其語(yǔ)法類似于Java,也有注釋、關(guān)鍵字、類型、變量、函數(shù)等,其就要相對(duì)于其他腳本高出幾倍的性能,并且安全可靠,可以用于內(nèi)聯(lián)和存儲(chǔ)腳本。
-
支持的語(yǔ)言
-
groovy:ES 1.4.x-5.0的默認(rèn)腳本語(yǔ)言
-
painless:JavaEE使用java語(yǔ)言開發(fā),.Net使用C#/F#語(yǔ)言開發(fā),Flutter使用Dart語(yǔ)言開發(fā),同樣,ES 5.0+版本后的Scripting使用的語(yǔ)言默認(rèn)就是painless,painless是一種專門用于Elasticsearch的簡(jiǎn)單,用于內(nèi)聯(lián)和存儲(chǔ)腳本,是ES 5.0+的默認(rèn)腳本語(yǔ)言,類似于Java,也有注釋、關(guān)鍵字、類型、變量、函數(shù)等,是一種安全的腳本語(yǔ)言。并且是Elasticsearch的默認(rèn)腳本語(yǔ)言。
-
其他:
expression:每個(gè)文檔的開銷較低:表達(dá)式的作用更多,可以非??焖俚貓?zhí)行,甚至比編寫native腳本還要快,支持javascript語(yǔ)法的子集:單個(gè)表達(dá)式。缺點(diǎn):只能訪問數(shù)字,布爾值,日期和geo_point字段,存儲(chǔ)的字段不可用
mustache:提供模板參數(shù)化查詢
-
-
特點(diǎn)
- 語(yǔ)法簡(jiǎn)單,學(xué)習(xí)成本低
- 靈活度高,可編程能力強(qiáng)
- 性能相較于其他腳本語(yǔ)言很高
- 安全性好
- 獨(dú)立語(yǔ)言,雖然易學(xué)但仍需單獨(dú)學(xué)習(xí)
- 相較于DSL性能低
- 不適用于復(fù)雜的業(yè)務(wù)場(chǎng)景
-
應(yīng)用場(chǎng)景:各種復(fù)雜的應(yīng)用場(chǎng)景,如自定義評(píng)分、自定義聚合查詢等。
-
正則:
早先某些版本正則表達(dá)式默認(rèn)情況下處于禁用模式,因?yàn)樗@過了painless的針對(duì)長(zhǎng)時(shí)間運(yùn)行和占用內(nèi)存腳本的保護(hù)機(jī)制。而且有深度對(duì)戰(zhàn)行為。如果需要開啟正則,需要配置:script.painless.regex.enabled: true
注意:通常正則的使用范圍比較小,應(yīng)用范圍基本限制在數(shù)據(jù)量比較小和并發(fā)量比較小的應(yīng)用場(chǎng)景下。
-
doc[‘field’].value和params[‘_source’][‘field’]:
理解之間的區(qū)別是很重要的,doc[‘field’].value和params[‘_source’][‘field’]。首先,使用doc關(guān)鍵字,將導(dǎo)致該字段的條件被加載到內(nèi)存(緩存),這將導(dǎo)致更快的執(zhí)行,但更多的內(nèi)存消耗。此外,doc[…]符號(hào)只允許簡(jiǎn)單類型(不能返回一個(gè)復(fù)雜類型(JSON對(duì)象或者nested類型)),只有在非分析或單個(gè)詞條的基礎(chǔ)上有意義。但是,doc如果可能,使用仍然是從文檔訪問值的推薦方式,因?yàn)開source每次使用時(shí)都必須加載并解析。使用_source非常緩慢
腳本查詢-實(shí)戰(zhàn)教程
1、對(duì)索引中的數(shù)據(jù)進(jìn)行修改
價(jià)格減一
POST product/_update/2
{"script": {"source": "ctx._source.price-=1"}
}小米10出了新款 新增了tag 叫做“無線充電”
POST product/_update/6
{"script": {"lang": "painless","source": "ctx._source.tags.add('無線充電')"}
}
2、將文檔從一個(gè)索引復(fù)制到另一個(gè)索引。它允許用戶將數(shù)據(jù)從一個(gè)索引重新索引到另一個(gè)索引
POST _reindex
{"source": {"index": "product"},"dest": {"index": "product2"}
}
3、刪除索引中的數(shù)據(jù)
執(zhí)行delete操作
POST product/_update/10
{"script": {"lang": "painless","source": "ctx.op='delete'"}
}
4、upsert有則更新否則插入
POST product/_update/19
{"script": {"lang": "painless","source": "ctx._source.price += 100"},"upsert": {"name" : "小米手機(jī)10","desc" : "充電賊快掉電更快,超級(jí)無敵望遠(yuǎn)鏡,高刷電競(jìng)屏","price" : 1999}
}
5、參數(shù)化操作索引數(shù)據(jù)
POST product/_update/6
{"script": {"lang": "painless","source": "ctx._source.tags.add(params.tag_name)","params": {"tag_name":"無線秒充"}}
}
6、對(duì)索引數(shù)據(jù)進(jìn)行多次操作
GET product/_search
{"script_fields": {"price": {"script": {"lang": "painless","source": "doc['price'].value"}},"discount_price": {"script": {"lang": "painless","source": "[doc['price'].value* params.discount_8,doc['price'].value* params.discount_7,doc['price'].value* params.discount_6,doc['price'].value* params.discount_5]","params": {"discount_8": 0.8,"discount_7": 0.7,"discount_6": 0.6,"discount_5": 0.5}}}}
}
7、模板腳本
#創(chuàng)建腳本模板
POST _scripts/calculate_discount
{"script": {"lang": "painless","source": "doc.price.value * params.discount"}
}
#查看
GET _scripts/calculate_discount
#使用模板進(jìn)行數(shù)據(jù)運(yùn)算
GET product/_search
{"script_fields": {"price": {"script": {"lang": "painless","source": "doc['price'].value"}},"discount_fields": {"script": {"id": "calculate_discount","params": {"discount":0.8}}}}
}
8、函數(shù)式編程
#Scripting的函數(shù)式編程
GET product/_search
GET product/_doc/1
POST product/_update/1
{"script": {"lang": "painless","source": "ctx._source.tags.add(params.tag_name)","params": {"tag_name":"無線秒充"}}
}POST product/_update/1
{"script": {"lang": "painless","source": """ctx._source.tags.add(params.tag_name);ctx._source.price-=100;""","params": {"tag_name":"無線秒充1"}}
}
9、正則表達(dá)式
#正則like %小米% /[\s\S]*小米[\s\S]*/
POST product/_update/4
{"script": {"lang": "painless","source": """if(ctx._source.name ==~ /[\s\S]*小米[\s\S]*/) {ctx._source.name+="***|"}else{ctx.op="noop"}"""}
}
#/\d{4}-\d{2}-\d{2}[\s\S]*/
GET product/_doc/1
POST product/_update/1
{"script": {"lang": "painless","source": """if(ctx._source.createtime ==~ /\d{4}-\d{2}-\d{2}[\s\S]*/) {ctx._source.name+="|***"}else{ctx.op="noop"}"""}
}
10、聚合查詢一起使用
GET product/_search
#統(tǒng)計(jì)所有價(jià)格小于1000的商品的tag的數(shù)量 不考慮重復(fù)的情況
GET product/_mapping
GET product/_search
{"query": {"constant_score": {"filter": {"range": {"price": {"lte": 1000}}}}},"aggs": {"tag_agg": {"sum": {"script": {"lang": "painless","source": """int total = 0;for(int i = 0; i <doc['tags.keyword'].length; i++){total++;}return total;"""}}}}
}