for(SearchHit?hit:searchHits){
//?文檔的主鍵
String?id?=?hit.getId();
//?源文檔內(nèi)容
Map<String,?Object>?sourceAsMap?=?hit.getSourceAsMap();
String?name?=?(String)?sourceAsMap.get(“name”);
//?由于前邊設(shè)置了源文檔字段過慮,這時description是取不到的
String?description?=?(String)?sourceAsMap.get(“description”);
//?學(xué)習(xí)模式
String?studymodel?=?(String)?sourceAsMap.get(“studymodel”);
//?價格
Double?price?=?(Double)?sourceAsMap.get(“price”);
//?日期
Date?timestamp?=?dateFormat.parse((String)?sourceAsMap.get(“timestamp”));
System.out.println(name);
System.out.println(studymodel);
System.out.println(“你看不見我,看不見我~”?+?description);
System.out.println(price);
}
}
坑:
執(zhí)行過程中遇到的問題:不能對這個值進(jìn)行初始化,導(dǎo)致 Spring 容器無法初始化
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'yunshangxue.elasticsearch.hostlist' in value "${yunshangxue.elasticsearch.hostlist}"
通過檢查 target 目錄發(fā)現(xiàn),生成的 target 文件包中沒有將 yml 配置文件帶過來… 仔細(xì)對比發(fā)現(xiàn),我的項目竟然變成了一個不是 Maven 的項目。重新使用 IDEA 導(dǎo)入 Mavaen 工程之后便能正常運行了。
推薦:Java面試練題寶典
分頁查詢
我們來 look 一下 ES 的分頁查詢參數(shù):
{
//?from?起始索引
//?size?每頁顯示的條數(shù)
“from”?:?0,?“size”?:?1,
“query”:?{
“match_all”:?{}
},
“_source”?:?[“name”,“studymodel”]
}
通過查詢結(jié)果可以發(fā)現(xiàn),我們設(shè)置了分頁參數(shù)之后, hits.total 仍然是 3,表示它找到了 3 條數(shù)據(jù),而按照分頁規(guī)則,它只會返回一條數(shù)據(jù),因此 hits.hits 里面只有一條數(shù)據(jù)。這也符合我們的業(yè)務(wù)規(guī)則,在查詢前端頁面顯示總共的條數(shù)和當(dāng)前的數(shù)據(jù)。
由此,我們就可以通過 Java API 來構(gòu)建查詢條件了:對上面查詢?nèi)康拇a進(jìn)行如下改造:
//?搜索源構(gòu)建對象
SearchSourceBuilder?searchSourceBuilder?=?new?SearchSourceBuilder();
int?page?=?2;?//?頁碼
int?size?=?1;?//?每頁顯示的條數(shù)
int?index?=?(page?-?1)?*?size;
searchSourceBuilder.from(index);
searchSourceBuilder.size(1);
//?搜索方式
//?matchAllQuery搜索全部
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
精確查詢 TermQuery
Term Query為精確查詢,在搜索時會整體匹配關(guān)鍵字,不再將關(guān)鍵字分詞
例如:
{
“query”:?{
“term”:?{?//?查詢的方式為?term?精確查詢
“name”:?“spring”?//?查詢的字段為?name?關(guān)鍵字是?spring
}
},
“_source”:?[
“name”,
“studymodel”
]
}
此時查詢的結(jié)果是:
“hits”:?[
{
“_index”:?“ysx_course”,
“_type”:?“doc”,
“_id”:?“3”,
“_score”:?0.9331132,
“_source”:?{
“studymodel”:?“201001”,
“name”:?“spring開發(fā)基礎(chǔ)”
}
}
]
查詢到了上面這條數(shù)據(jù),因為 spring開發(fā)基礎(chǔ) 分完詞后是 spring 開發(fā) 基礎(chǔ) ,而查詢關(guān)鍵字是 spring 不分詞,這樣當(dāng)然可以匹配到這條記錄,但是當(dāng)我們修改關(guān)鍵字為 spring開發(fā),按照往常的查詢方法,也是可以查詢到的。但是 term 不一樣,它不會對關(guān)鍵字分詞。結(jié)果可想而知是查詢不到的
JavaAPI如下:
//?搜索方式
//?termQuery?精確查詢
searchSourceBuilder.query(QueryBuilders.termQuery(“studymodel”,?“201002”));
根據(jù) ID 查詢:
根據(jù) ID 精確查詢和根據(jù)其他條件精確查詢是一樣的,不同的是 id 字段前面有一個下劃線注意寫上
searchSourceBuilder.query(QueryBuilders.termQuery(“_id”,?“1”));
但是,當(dāng)一次查詢多個 ID 時,相應(yīng)的 API 也應(yīng)該改變,使用 termsQuery 而不是 termQuery。多了一個 s
全文檢索 MatchQuery
MatchQuery 即全文檢索,會對關(guān)鍵字進(jìn)行分詞后匹配詞條。
query:搜索的關(guān)鍵字,對于英文關(guān)鍵字如果有多個單詞則中間要用半角逗號分隔,而對于中文關(guān)鍵字中間可以用逗號分隔也可以不用
operator:設(shè)置查詢的結(jié)果取交集還是并集,并集用 or, 交集用 and
{
“query”:?{
“match”:?{
“description”:?{
“query”:?“spring開發(fā)”,
“operator”:?“or”
}
}
}
}
有時,我們需要設(shè)定一個量化的表達(dá)方式,例如查詢 spring開發(fā)基礎(chǔ),這三個詞條。我們需求是至少匹配兩個詞條,這時 operator 屬性就不能滿足要求了,ES 還提供了另外一個屬性:minimum_should_match
?用一個百分?jǐn)?shù)來設(shè)定應(yīng)該有多少個詞條滿足要求。例如查詢:
“spring開發(fā)框架”會被分為三個詞:spring、開發(fā)、框架
設(shè)置"minimum_should_match": "80%"
表示,三個詞在文檔的匹配占比為80%,即3*0.8=2.4
,向下取整得2,表示至少有兩個詞在文檔中要匹配成功。
推薦:Java面試練題寶典
JavaAPI
通過 matchQuery.minimumShouldMatch 的方式來設(shè)置條件
//?matchQuery全文檢索
searchSourceBuilder.query(QueryBuilders.matchQuery(“description”,?“Spring開發(fā)框架”).minimumShouldMatch(“70%”));
多字段聯(lián)合搜索 MultiQuery
上面的 MatchQuery 有一個短板,假如用戶輸入了某關(guān)鍵字,我們在查找的時候并不知道他輸入的是 name 還是 description,這時我們用什么都不合適,而 MultiQuery 的出現(xiàn)解決了這個問題,他可以通過 fields 屬性來設(shè)置多個域聯(lián)合查找:具體用法如下
{
“query”:?{
“multi_match”:?{
“query”:?“Spring開發(fā)”,
“minimum_should_match”:?“70%”,
“fields”:?[“name”,?“description”]
}
}
}
JavaAPI
searchSourceBuilder.query(QueryBuilders.multiMatchQuery(“Spring開發(fā)框架”,?“name”,?“description”).minimumShouldMatch(“70%”));
提升 boost
在多域聯(lián)合查詢的時候,可以通過 boost 來設(shè)置某個域在計算得分時候的比重,比重越高的域當(dāng)他符合條件時計算的得分越高,相應(yīng)的該記錄也更靠前。通過在 fields 中給相應(yīng)的字段用 ^權(quán)重倍數(shù)來實現(xiàn)
“fields”:?[“name^10”,?“description”]
上面的代碼表示給 name 字段提升十倍權(quán)重,查詢到的結(jié)果:
{
“_index”:?“ysx_course”,
“_type”:?“doc”,
“_id”:?“3”,
“_score”:?13.802518,?//?可以清楚的發(fā)現(xiàn),得分竟然是?13?了
“_source”:?{
“name”:?“spring開發(fā)基礎(chǔ)”,
“description”:?“spring 在java領(lǐng)域非常流行,java程序員都在用?!?
“studymodel”:?“201001”,
“price”:?88.6,
“timestamp”:?“2018-02-24?19:11:35”,
“pic”:?“group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg”
}
},
而在 Java 中,仍然可以通過鏈?zhǔn)骄幊虂韺崿F(xiàn)
searchSourceBuilder.query(QueryBuilders.multiMatchQuery(“Spring開發(fā)框架”,?“name”,?“description”).field(“name”,?10));?//?設(shè)置?name?10倍權(quán)重
布爾查詢 BoolQuery
如果我們既要對一些字段進(jìn)行分詞查詢,同時要對另一些字段進(jìn)行精確查詢,就需要使用布爾查詢來實現(xiàn)了。布爾查詢對應(yīng)于Lucene的BooleanQuery查詢,實現(xiàn)將多個查詢組合起來,有三個可選的參數(shù):
must:文檔必須匹配must所包括的查詢條件,相當(dāng)于 “AND”
should:文檔應(yīng)該匹配should所包括的查詢條件其中的一個或多個,相當(dāng)于 “OR”
must_not:文檔不能匹配must_not所包括的該查詢條件,相當(dāng)于“NOT”
{
“query”:?{
“bool”:?{?//?布爾查詢
“must”:?[?//?查詢條件?must?表示數(shù)組中的查詢方式所規(guī)定的條件都必須滿足
{
“multi_match”:?{
“query”:?“spring框架”,
“minimum_should_match”:?“50%”,
“fields”:?[
“name^10”,
“description”
]
}
},
{
“term”:?{
“studymodel”:?“201001”
}
}
]
}
}
}
JavaAPI
//?搜索方式
//?首先構(gòu)造多關(guān)鍵字查詢條件
MultiMatchQueryBuilder?matchQueryBuilder?=?QueryBuilders.multiMatchQuery(“Spring開發(fā)框架”,?“name”,?“description”).field(“name”,?10);
//?然后構(gòu)造精確匹配查詢條件
TermQueryBuilder?termQueryBuilder?=?QueryBuilders.termQuery(“studymodel”,?“201002”);
//?組合兩個條件,組合方式為?must?全滿足
BoolQueryBuilder?boolQueryBuilder?=?QueryBuilders.boolQuery();
boolQueryBuilder.must(matchQueryBuilder);
boolQueryBuilder.must(termQueryBuilder);
//?將查詢條件封裝給查詢對象
searchSourceBuilder.query(boolQueryBuilder);
過濾器
定義過濾器查詢,是在原本查詢結(jié)果的基礎(chǔ)上對數(shù)據(jù)進(jìn)行篩選,因此省略了重新計算的分的步驟,效率更高。并且方便緩存。推薦盡量使用過慮器去實現(xiàn)查詢或者過慮器和查詢共同使用,過濾器在布爾查詢中使用,下邊是在搜索結(jié)果的基礎(chǔ)上進(jìn)行過濾:
{
“query”:?{
“bool”:?{
“must”:?[
{
“multi_match”:?{
“query”:?“spring框架”,
“minimum_should_match”:?“50%”,
“fields”:?[
“name^10”,
“description”
]
}
}
],
“filter”:?[
{
//?過濾條件:studymodel 必須是 201001
“term”:?{“studymodel”:?“201001”}
},
{
//?過濾條件:價格?>=60?<=100
“range”:?{“price”:?{“gte”:?60,“l(fā)te”:?100}}
}
]
}
}
}
注意:range和term一次只能對一個Field設(shè)置范圍過慮。
JavaAPI
//?首先構(gòu)造多關(guān)鍵字查詢條件
MultiMatchQueryBuilder?matchQueryBuilder?=?QueryBuilders.multiMatchQuery(“Spring框架”,?“name”,?“description”).field(“name”,?10);
//?添加條件到布爾查詢
BoolQueryBuilder?boolQueryBuilder?=?QueryBuilders.boolQuery();
boolQueryBuilder.must(matchQueryBuilder);
//?通過布爾查詢來構(gòu)造過濾查詢
boolQueryBuilder.filter(QueryBuilders.termQuery(“studymodel”,?“201001”));
boolQueryBuilder.filter(QueryBuilders.rangeQuery(“price”).gte(60).lte(100));
//?將查詢條件封裝給查詢對象
searchSourceBuilder.query(boolQueryBuilder);
排序
我們可以在查詢的結(jié)果上進(jìn)行二次排序,支持對 keyword、date、float 等類型添加排序,text類型的字段不允許排序。排序使用的 JSON 格式如下:
{
“query”:?{
“bool”:?{
“filter”:?[
{
“range”:?{
“price”:?{
“gte”:?0,
“l(fā)te”:?100
}
}
}
]
}
},
“sort”:?[?//?注意這里排序是寫在 query key 的外面的。這就表示它的API也不是布爾查詢提供
{
“studymodel”:?“desc”?//?對?studymodel(keyword)降序
},
{
“price”:?“asc”?//?對?price(double)升序
}
]
}
由上面的 JSON 數(shù)據(jù)可以發(fā)現(xiàn),排序所屬的 API 是和 query 評級的,因此在調(diào)用 API 時也應(yīng)該選擇對應(yīng)的 SearchSourceBuilder 對象
//?排序查詢
@Test
public?void?testSort()?throws?IOException,?ParseException?{
//?搜索請求對象
SearchRequest?searchRequest?=?new?SearchRequest(“ysx_course”);
//?指定類型
searchRequest.types(“doc”);
//?搜索源構(gòu)建對象
SearchSourceBuilder?searchSourceBuilder?=?new?SearchSourceBuilder();
//?搜索方式
//?添加條件到布爾查詢
BoolQueryBuilder?boolQueryBuilder?=?QueryBuilders.boolQuery();
//?通過布爾查詢來構(gòu)造過濾查詢
boolQueryBuilder.filter(QueryBuilders.rangeQuery(“price”).gte(0).lte(100));
//?將查詢條件封裝給查詢對象
searchSourceBuilder.query(boolQueryBuilder);
//?向搜索請求對象中設(shè)置搜索源
searchRequest.source(searchSourceBuilder);
//?設(shè)置排序規(guī)則
searchSourceBuilder.sort(“studymodel”,?SortOrder.DESC);?//?第一排序規(guī)則
searchSourceBuilder.sort(“price”,?SortOrder.ASC);?//?第二排序規(guī)則
//?執(zhí)行搜索,向ES發(fā)起http請求
SearchResponse?searchResponse?=?client.search(searchRequest);
//?搜索結(jié)果
SearchHits?hits?=?searchResponse.getHits();
//?匹配到的總記錄數(shù)
long?totalHits?=?hits.getTotalHits();
//?得到匹配度高的文檔
SearchHit[]?searchHits?=?hits.getHits();
//?日期格式化對象
soutData(searchHits);
}
高亮顯示
小編13年上海交大畢業(yè),曾經(jīng)在小公司待過,也去過華為、OPPO等大廠,18年進(jìn)入阿里一直到現(xiàn)在。
深知大多數(shù)初中級Java工程師,想要提升技能,往往是自己摸索成長,但自己不成體系的自學(xué)效果低效又漫長,而且極易碰到天花板技術(shù)停滯不前!
因此收集整理了一份《2024年最新Java開發(fā)全套學(xué)習(xí)資料》送給大家,初衷也很簡單,就是希望能夠幫助到想自學(xué)提升又不知道該從何學(xué)起的朋友,同時減輕大家的負(fù)擔(dān)。
由于文件比較大,這里只是將部分目錄截圖出來,每個節(jié)點里面都包含大廠面經(jīng)、學(xué)習(xí)筆記、源碼講義、實戰(zhàn)項目、講解視頻
如果你覺得這些內(nèi)容對你有幫助,可以添加下面V無償領(lǐng)?。。▊渥ava)
讀者福利
更多筆記分享
earchHits?hits?=?searchResponse.getHits();
//?匹配到的總記錄數(shù)
long?totalHits?=?hits.getTotalHits();
//?得到匹配度高的文檔
SearchHit[]?searchHits?=?hits.getHits();
//?日期格式化對象
soutData(searchHits);
}
高亮顯示
小編13年上海交大畢業(yè),曾經(jīng)在小公司待過,也去過華為、OPPO等大廠,18年進(jìn)入阿里一直到現(xiàn)在。
深知大多數(shù)初中級Java工程師,想要提升技能,往往是自己摸索成長,但自己不成體系的自學(xué)效果低效又漫長,而且極易碰到天花板技術(shù)停滯不前!
因此收集整理了一份《2024年最新Java開發(fā)全套學(xué)習(xí)資料》送給大家,初衷也很簡單,就是希望能夠幫助到想自學(xué)提升又不知道該從何學(xué)起的朋友,同時減輕大家的負(fù)擔(dān)。
[外鏈圖片轉(zhuǎn)存中…(img-89dZ6vAB-1711155995487)]
[外鏈圖片轉(zhuǎn)存中…(img-zklbwSe7-1711155995488)]
[外鏈圖片轉(zhuǎn)存中…(img-ou6Iy4Hc-1711155995489)]
由于文件比較大,這里只是將部分目錄截圖出來,每個節(jié)點里面都包含大廠面經(jīng)、學(xué)習(xí)筆記、源碼講義、實戰(zhàn)項目、講解視頻
如果你覺得這些內(nèi)容對你有幫助,可以添加下面V無償領(lǐng)?。。▊渥ava)
[外鏈圖片轉(zhuǎn)存中…(img-A4BUoMjE-1711155995489)]
讀者福利
[外鏈圖片轉(zhuǎn)存中…(img-7uKs5bkw-1711155995489)]
更多筆記分享
[外鏈圖片轉(zhuǎn)存中…(img-zDfnj2R6-1711155995490)]文章來源:http://www.zghlxwxcb.cn/news/detail-856746.html
本文已被CODING開源項目:【一線大廠Java面試題解析+核心總結(jié)學(xué)習(xí)筆記+最新講解視頻+實戰(zhàn)項目源碼】收錄文章來源地址http://www.zghlxwxcb.cn/news/detail-856746.html
到了這里,關(guān)于SpringBoot操作ES進(jìn)行各種高級查詢(值得收藏),阿里P7大佬手把手教你的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!