起因:在項(xiàng)目開發(fā)過程中胳蛮,要使用到搜索 引擎來對一些關(guān)鍵字實(shí)現(xiàn)逆向查詢销凑,如果僅用模糊搜索,那么搜索的時(shí)間會根據(jù)數(shù)據(jù)量的增大而增大仅炊,對比之下就學(xué)了elasticsearch斗幼,也記錄一下,常掣ⅲ回顧蜕窿。
1. Elasticsearch進(jìn)行基礎(chǔ)數(shù)據(jù)搭建及QueryString查詢
1.1. 基礎(chǔ)數(shù)據(jù)的準(zhǔn)備
所有的數(shù)據(jù)都要在index這個(gè)容器下
就要錄入document,_id:是文檔的id督勺,他和你內(nèi)容數(shù)據(jù)id是沒有關(guān)系
-
比如說操作商品數(shù)據(jù)(product渠羞,variants,images智哀,tags)還是以商品id作為業(yè)務(wù)主鍵
/_doc/1/_update #我們不能為這個(gè)_id再保存一個(gè)關(guān)系到數(shù)據(jù)庫次询,所以一般_id和我們的業(yè)務(wù)主鍵一致
比如圖片路徑不用索引:index:false
比如需要精確查詢的內(nèi)容:type:keyword
一定要手工創(chuàng)建mapping,設(shè)置你需要的類型和分詞器
POST /index_customer/_mapping
{
"properties": {
"id": {
"type": "long"
},
"age": {
"type": "integer"
},
"username": {
"type": "keyword"
},
"nickname": {
"type": "text",
"analyzer": "ik_max_word"
},
"consume": {
"type": "float"
},
"desc": {
"type": "text",
"analyzer": "ik_max_word"
},
"sex": {
"type": "byte"
},
"borthday": {
"type": "date"
},
"faceimg": {
"type": "text",
"index": false
}
}
}
# 回憶一下分詞器的概念
POST /index_customer/_analyze
{
"field": "nickname",
"text": "今晚路上的車非常通暢瓷叫,我提前到公司了"
}
錄入數(shù)據(jù)
# POST /index_customer/_doc/1001
{
"id": 1001,
"age": 24,
"username": "kingliu",
"nickname": "飛上天空做太陽",
"consume": 1289.88,
"desc": "我在艾編程學(xué)習(xí)java和vue屯吊,學(xué)習(xí)到了很多知識",
"sex": 1,
"birthday": "1996-12-24",
"faceimg": "https://www.icodingedu.com/img/customers/1001/logo.png"
}
# POST /index_customer/_doc/1002
{
"id": 1002,
"age": 26,
"username": "lucywang",
"nickname": "夜空中最亮的星",
"consume": 6699.88,
"desc": "我在艾編程學(xué)習(xí)VIP課程,非常打動我",
"sex": 0,
"birthday": "1994-02-24",
"faceimg": "https://www.icodingedu.com/img/customers/1002/logo.png"
}
# POST /index_customer/_doc/1003
{
"id": 1003,
"age": 30,
"username": "kkstar",
"nickname": "照亮你的星",
"consume": 7799.66,
"desc": "老師們授課風(fēng)格不同摹菠,但結(jié)果卻是異曲同工盒卸,講的很不錯(cuò),值得推薦",
"sex": 1,
"birthday": "1990-12-02",
"faceimg": "https://www.icodingedu.com/img/customers/1003/logo.png"
}
# POST /index_customer/_doc/1004
{
"id": 1004,
"age": 31,
"username": "alexwang",
"nickname": "騎著老虎看日出",
"consume": 9799.66,
"desc": "課程內(nèi)容充實(shí)次氨,有料蔽介,很有吸引力,贊一個(gè)",
"sex": 1,
"birthday": "1989-05-09",
"faceimg": "https://www.icodingedu.com/img/customers/1004/logo.png"
}
# POST /index_customer/_doc/1005
{
"id": 1005,
"age": 32,
"username": "jsonzhang",
"nickname": "我是你的神話",
"consume": 12789.66,
"desc": "需要抽時(shí)間把所有內(nèi)容都學(xué)個(gè)遍,太給力料",
"sex": 1,
"birthday": "1988-07-19",
"faceimg": "https://www.icodingedu.com/img/customers/1005/logo.png"
}
# POST /index_customer/_doc/1006
{
"id": 1006,
"age": 27,
"username": "abbyli",
"nickname": "好甜的棉花糖",
"consume": 10789.86,
"desc": "還不錯(cuò),內(nèi)容超過我的預(yù)期值,錢花的值",
"sex": 0,
"birthday": "1993-10-11",
"faceimg": "https://www.icodingedu.com/img/customers/1006/logo.png"
}
# POST /index_customer/_doc/1007
{
"id": 1007,
"age": 33,
"username": "jacktian",
"nickname": "船長jack",
"consume": 9789.86,
"desc": "一直想抽時(shí)間學(xué)習(xí)宋光,這下有時(shí)間整了罪佳,給力",
"sex": 1,
"birthday": "1987-09-16",
"faceimg": "https://www.icodingedu.com/img/customers/1007/logo.png"
}
# POST /index_customer/_doc/1008
{
"id": 1008,
"age": 23,
"username": "feifei",
"nickname": "我愛籃球",
"consume": 6689.86,
"desc": "雖然又一些不太懂菇民,但只要有時(shí)間投储,相信一定能學(xué)好的",
"sex": 1,
"birthday": "1997-04-18",
"faceimg": "https://www.icodingedu.com/img/customers/1008/logo.png"
}
# POST /index_customer/_doc/1009
{
"id": 1009,
"age": 25,
"username": "daisyzhang",
"nickname": "一起看日出",
"consume": 6680,
"desc": "學(xué)習(xí)起來還是很有意思的玛荞,值得我多次學(xué)習(xí)",
"sex": 0,
"birthday": "1995-03-27",
"faceimg": "https://www.icodingedu.com/img/customers/1009/logo.png"
}
# POST /index_customer/_doc/1010
{
"id": 1010,
"age": 29,
"username": "ethenhe",
"nickname": "旋風(fēng)小子",
"consume": 6699.99,
"desc": "課程嚴(yán)謹(jǐn)勋眯,知識豐富下梢,講解到位,編程給力",
"sex": 1,
"birthday": "1991-06-22",
"faceimg": "https://www.icodingedu.com/img/customers/1010/logo.png"
}
# POST /index_customer/_doc/1011
{
"id": 1011,
"age": 27,
"username": "lydiazheng",
"nickname": "跳芭蕾的小妮",
"consume": 8899.99,
"desc": "自己一直都沒有動力去系統(tǒng)學(xué)習(xí)讶坯,這次有了老師和大家的督促辆琅,非常不錯(cuò)这刷,終于堅(jiān)持下來了",
"sex": 0,
"birthday": "1993-08-27",
"faceimg": "https://www.icodingedu.com/img/customers/1011/logo.png"
}
# POST /index_customer/_doc/1012
{
"id": 1012,
"age": 37,
"username": "draglong",
"nickname": "飛龍?jiān)谔?,
"consume": 18899.99,
"desc": "技術(shù)宅暇屋,就喜歡研究技術(shù),和大家碰撞感覺很好",
"sex": 1,
"birthday": "1983-11-22",
"faceimg": "https://www.icodingedu.com/img/customers/1012/logo.png"
}
QueryString的查詢方式
/index_customer/_search?q=desc:艾編程&q=age:24
2. Elasticsearch的DSL查詢語法
QueryString實(shí)際業(yè)務(wù)中使用非常少屋彪,一旦需要復(fù)雜的查詢條件绒尊,就需要DSL來進(jìn)行查詢
- Domain Specific Language
- 特定領(lǐng)域的語言
- 內(nèi)容是基于json
- 查詢靈活方便婴谱,有利于復(fù)雜查詢
POST /index_customer/_doc/_search
{
"query": {
"match": {
"desc": "艾編程"
}
}
}
POST /index_customer/_doc/_search #判斷字段是否存在谭羔,如果存在將字段相關(guān)的所有數(shù)據(jù)展示
{
"query": {
"exists": {
"field": "desc"
}
}
}
3. DSL查詢所有數(shù)據(jù)及分頁&文檔ID搜索
# 查詢所有數(shù)據(jù)并進(jìn)行filter過濾
POST /index_customer/_doc/_search
{
"query": {
"match_all":{}
},
"_source": ["id","nickname","age"]
}
# 分頁 from從第幾個(gè)開始,0開始節(jié)點(diǎn)
POST /index_customer/_doc/_search
{
"query": {
"match_all":{}
},
"_source": ["id","nickname","age"],
"from": 0,
"size": 5
}
DSL進(jìn)行文檔ID的精確搜索
GET /index_customer/_doc/1001
GET /index_customer/_doc/1002?_source=id,nickname,age
# 我們要通過DSL一次查詢出多個(gè)ID
POST /index_customer/_search
{
"query":{
"ids": {
"type": "_doc",
"values": ["1001","1010","1012"]
}
},
"_source": ["id","username","nickname","desc"]
}
4. DSL的term&math&terms匹配查詢
# term查詢,將條件里的詞不進(jìn)行分詞來查詢
POST /index_customer/_search
{
"query":{
"term": {
"desc": "艾編程"
}
}
}
# match查詢,將條件里的詞使用這個(gè)field的分詞器進(jìn)行分詞后和field里的分詞逐一匹配
POST /index_customer/_search
{
"query":{
"match": {
"desc": "艾編程"
}
}
}
# terms查詢,將條件里的詞不進(jìn)行分詞來查詢,但可以設(shè)置多個(gè)
POST /index_customer/_search
{
"query":{
"terms": {
"desc": ["艾編程","編程"]
}
}
}
5. DSL的match相關(guān)搜索查詢及boost權(quán)重設(shè)置
5.1. math_phrase
match對查詢條件分詞后只要有匹配,哪怕是一個(gè)詞话告,也會返回
math_phrase:分詞結(jié)果必須都包含沙郭,并且是相鄰(搜索比較嚴(yán)格)
如果有這么一篇文章
# springboot elasticsearch dsl
1、springboot 安裝使用
2吓著、elasticsearch 安裝使用
3绑莺、es的DSL查詢使用
# 其實(shí)你心里的想法是springboot下如何操作elasticsearch進(jìn)行DSL查詢
短語匹配
# query里的詞必須都匹配惕耕,而且還要相鄰
# slop: 允許詞語間跳過的數(shù)量,默認(rèn)可以不寫对扶,不寫是挨著的沒有跳數(shù)
{
"query": {
"match_phrase": {
"desc": {
"query": "艾編程 知識",
"slop": 9
}
}
}
}
5.2. mach擴(kuò)展:operator
- or:搜索的分詞內(nèi)容浪南,只要有一個(gè)詞語匹配就展示
- and:搜索的分詞內(nèi)容必須全部匹配
POST /index_customer/_search
{
"query": {
"match": {
"desc": {
"query": "我在艾編程",
"operator": "and"
}
}
}
}
# or就是常規(guī)match查詢
{
"query":{
"match": {
"desc": "艾編程"
}
}
}
5.3. mach擴(kuò)展:minimum_should_match
minimum_should_match:最低匹配精度络凿,配置有兩種,一種是占比:60%摔踱,只要有任意 6個(gè)詞就展示出結(jié)果 6/10個(gè)分詞=60%怨愤,還有一種絕對值:可以直接寫數(shù)字:6,至少要6個(gè)詞都匹配
POST /index_customer/_search
{
"query": {
"match": {
"desc": {
"query": "我在艾編程學(xué)習(xí)",
"minimum_should_match": "40%"
}
}
}
}
5.4. multi_match
POST /index_customer/_search
{
"query": {
"multi_match": {
"query": "我在艾編程學(xué)習(xí)神話",
"fields": [
"desc",
"nickname"
]
}
}
}
5.5. 修改默認(rèn)的排序權(quán)重
權(quán)重篮愉,為某個(gè)字段設(shè)置查詢權(quán)重试躏,權(quán)重越高颠蕴,文檔相關(guān)性越高_(dá)score越高助析,查詢結(jié)果約靠前
# "nickname^10" 代表在這個(gè)列上如果查詢到數(shù)據(jù),就會將相關(guān)性放大10倍
POST /index_customer/_search
{
"query": {
"multi_match": {
"query": "我在艾編程學(xué)習(xí)神話",
"fields": [
"desc",
"nickname^10"
]
}
}
}
6. DSL之布爾查詢&為指定語句加權(quán)
布爾查詢就是bool弱判,其實(shí)就是多條件組合查詢锥惋,可以在不同列上進(jìn)行
- must:查詢必須匹配所有搜索條件膀跌,類似and
- should:查詢只要匹配一個(gè)搜索條件即可捅伤,類似or
- must_not:不匹配搜索條件的內(nèi)容巫玻,一個(gè)都不要滿足,類似not
這里要注意的點(diǎn)
# must熄诡、should凰浮、must_not雖然語法可以并列
# must和should同時(shí)寫,只有must生效
# must和must_not同時(shí)寫菜拓,會在must符合后進(jìn)行must_not條件剔除
業(yè)務(wù)場景描述:
desc里有:日出纳鼎,并且username是jacktian或nickname里有學(xué)習(xí)的數(shù)據(jù)
# 解決方案一
{
"query": {
"bool": {
"must": [
{
"match": {
"desc": "學(xué)習(xí)"
}
}
],
"should": [
{
"match": {
"nickname": "日出"
}
},
{
"term": {
"username": "jacktian"
}
}
],
"minimum_should_match": 1
}
}
}
# 方案二
# desc='學(xué)習(xí)' and (nickname='日出' or username='jacktian')
{
"query": {
"bool": {
"must": [
{
"match": {
"desc": "學(xué)習(xí)"
}
},
{
"bool": {
"should": [
{
"match": {
"nickname": "日出"
}
},
{
"term": {
"username": "jacktian"
}
}
]
}
}
]
}
}
}
# 方案三
# (desc='學(xué)習(xí)' and nickname='日出') or (desc='學(xué)習(xí)' and username='jacktian')
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match": {
"nickname": {
"query": "日出",
"boost": 10
}
}
},
{
"match": {
"desc": "學(xué)習(xí)"
}
}
]
}
},
{
"bool": {
"must": [
{
"match": {
"desc": "學(xué)習(xí)"
}
},
{
"term": {
"username": "jacktian"
}
}
]
}
}
]
}
}
}
# "boost": 10 就是給字段增加權(quán)重的方式
7. DSL搜索過濾器&搜索排序&搜索結(jié)果高亮
- query:是根據(jù)用戶搜索條件檢索匹配記錄
- post_filter:用于查詢后,對結(jié)果數(shù)據(jù)進(jìn)行篩選
# gte : 大于等于
# lte : 小于等于
# gt : 大于
# lt : 小于
POST /index_customer/_search
{
"query": {
"match": {
"desc": "我在艾編程學(xué)習(xí)"
}
},
"post_filter": {
"range": {
"consume": {
"gt": 10000,
"lt": 20000
}
}
}
}
# 過濾也可以在query的結(jié)果基礎(chǔ)上再做其他field的分詞
POST /index_customer/_search
{
"query": {
"match": {
"desc": "我在艾編程學(xué)習(xí)"
}
},
"post_filter": {
"match": {
"nickname": "太陽"
}
}
}
排序
POST /index_customer/_search
{
"query": {
"match": {
"desc": "我在艾編程學(xué)習(xí)"
}
},
"sort": [
{
"consume": "desc"
},
{
"age": "asc"
}
]
}
# 注意:sort是不能給text排序贰逾,但可以給keyword排序疙剑,因?yàn)閠ext會做分詞所以無法給多個(gè)分詞進(jìn)行排序践叠,keyword不會分詞所以可以
# 一般也不會給文本類型進(jìn)行排序禁灼,doc默認(rèn)排序規(guī)格是按照:文檔搜索的相關(guān)度打分_score,按照分?jǐn)?shù)降序
# 權(quán)重是影響_score分?jǐn)?shù)的因子
結(jié)果高亮顯現(xiàn)
# 高亮其實(shí)就是把我們搜索匹配到的關(guān)鍵字進(jìn)行顏色突出顯示僻孝,html<span></span>
POST /index_customer/_search
{
"query": {
"match": {
"desc": "我在艾編程學(xué)習(xí)"
}
},
"highlight": {
"pre_tags": [
"<span>"
],
"post_tags": [
"</span>"
],
"fields": {
"desc": {}
}
}
}
8. 其他DSL查詢方式
# prefix : 根據(jù)前綴去查詢
# fuzzy : 搜索引擎自動糾錯(cuò)的功能穿铆,icodinng.com 把幫我們糾錯(cuò)成icoding.com
# wildcard : 占位符查詢
? : 1個(gè)字符
* : N個(gè)字符
{
"query": {
"wildcard": {
"desc": "?艾編程*"
}
}
}
不要以為每天把功能完成了就行了斋荞,這種思想是要不得的,互勉~凤优!