1. 程式人生 > 其它 >記一次springboot+elasticsearch+mongodb查詢的使用

記一次springboot+elasticsearch+mongodb查詢的使用

技術標籤:java

記一次springboot+elasticsearch+mongodb查詢的使用

  • springboot:2.3.5
  • es:7.10.1
  • mongodb:4.4x
  • elasticsearch部署:參考其他教程
  • 源資料:使用的mongodb,因為mongodb查詢太慢所以使用es
  • elasticsearch同步mongodb資料:使用monstache
    – 注:由於資源有限,es和mongodb都放在同一臺伺服器上了,所以monstache的es地址設定成http://127.0.0.1:9200,(一開始沒寫http導致一直報錯es伺服器找不到node)部署在一臺伺服器上其實沒什麼用,就是饞es的搜尋功能。
  • 同步之後,伺服器上啟動了mongodb和es服務
  • springboot專案中使用elasticsearch,參考其他教程
  • 官方文件中推薦的是使用resthighlevelclient,這個的使用也有教程,但是參考官方文件比較好,官方文件對於hlc的講解也比較詳細
    –https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.10/java-rest-high-search.html
    –主要是構建query,client.search,再對searchResponse進行處理
  • 資料的物件處理參考其他教程
  • search之後得到map,轉化為java物件使用到了jackson工具類(最開始想直接set屬性,但是map還得判斷是否為null,之後使用阿里的fastjson但是效果一般,偶爾報錯,最後考慮jackson,確實nb)
  • 貼一段程式碼,分享一下模糊查詢和匹配查詢
SearchRequest searchRequest = new SearchRequest("project.paper");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
       
       //分頁操作
        searchSourceBuilder.from(pagenum*20);
        searchSourceBuilder.size(20);
       
        //設定超時
        searchSourceBuilder.
timeout(new TimeValue(30, TimeUnit.SECONDS)); searchRequest.source(searchSourceBuilder); //構建一個querybuilder MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("authors.name", name).fuzziness(Fuzziness.AUTO).maxExpansions(3); searchSourceBuilder.query(matchQueryBuilder); //獲取response SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT); return searchResponse;

我的理解是,querybuilder為查詢的方式,即如何查詢

這裡的MatchQueryBuilder是模糊匹配查詢,用了ik分詞器後模糊粒度還是很大。

想要做到通過單詞“keyword”查詢到“a test keyword”這個欄位的詞,還得用MatchPhraseBuilder,但是如果想要完全匹配,這個方法還是不行,因為查詢的關鍵字只要屬於欄位就會被返回。

實在想要實現精確匹配查詢,之後考慮了TermQueryBuilder,但是由於某種原因沒有成功返回資料,最後也沒有心情去追查原因。

最後實現了精確匹配,在用kibana玩耍的時候,發現es的資料中,每個欄位有兩個值,比如之前程式碼中的author.name,還存在另一個欄位author.name.keyword,通過實踐發現用這個欄位可以精確查詢,分詞器不會有影響。
kibana截圖

將之前的QueryBuilder的查詢欄位改為name.keyword

MatchPhraseQueryBuilder matchQueryBuilder = 
        new MatchPhraseQueryBuilder("authors.name.keyword", name);

具體原因暫時沒想要弄懂,不過這個keyword的效果應該和將欄位的type變成keyword是一樣的,但是又想使用text的分詞功能,所以有點矛盾,至於換成MatchQuery之後效果是否一樣也沒時間探究了,但是精確查詢這一塊,查了很多教程也沒有什麼進展,最後偶然發現,還是很有感觸的。

  • 最後:es7.10教程還是很少,大多隻能參考官方文件,好在這次只是使用了查詢功能,沒有很複雜,關於es多節點部署暫時沒有嘗試,只是想著先實現功能。
  • monstache參考:
    – https://blog.csdn.net/qq_28119741/article/details/109613212
    – 阿里雲文件:https://help.aliyun.com/document_detail/171650.html