日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Elasticsearch使用實戰以及代碼詳解

來源: 責編: 時間:2024-02-29 14:38:10 180觀看
導讀Elasticsearch 是一個使用 Java 語言編寫、遵守 Apache 協議、支持 RESTful 風格的分布式全文搜索和分析引擎,它基于 Lucene 庫構建,并提供多種語言的 API。Elasticsearch 可以對任何類型的數據進行索引、查詢和聚合分

Elasticsearch 是一個使用 Java 語言編寫、遵守 Apache 協議、支持 RESTful 風格的分布式全文搜索和分析引擎,它基于 Lucene 庫構建,并提供多種語言的 API。Elasticsearch 可以對任何類型的數據進行索引、查詢和聚合分析,無論是文本、數字、地理空間、結構化還是非結構化的。LFP28資訊網——每日最新資訊28at.com

Elasticsearch 的核心功能是搜索,它可以對數據進行分詞匹配、相關性評分、高亮顯示等操作,返回相關度高的結果列表。Elasticsearch 也可以用作數據分析,它可以對數據進行統計、分類、聚類等操作,返回聚合結果或圖表。LFP28資訊網——每日最新資訊28at.com

本文將用我開源的 waynboot-mall 項目作于代碼講解,Elasticsearch 版本是 7.10.1。LFP28資訊網——每日最新資訊28at.com

waynboot-mall 是一套全部開源的微商城項目,包含三個項目:運營后臺、H5 商城和后端接口。實現了一套完整的商城業務,有首頁展示、商品分類、商品詳情、sku 詳情、商品搜索、加入購物車、結算下單、支付寶/微信支付、訂單列表、商品評論等一系列功能。LFP28資訊網——每日最新資訊28at.com

本文大綱如下,LFP28資訊網——每日最新資訊28at.com

圖片圖片LFP28資訊網——每日最新資訊28at.com

應用場景

Elasticsearch 的典型應用場景有以下幾種:LFP28資訊網——每日最新資訊28at.com

  • 全文搜索:Elasticsearch 提供了全文搜索的功能,適用于電商商品搜索、App 搜索、企業內部信息搜索、IT 系統搜索等。例如我們可以為每一個商品作為文檔保存進 Elasticsearch,然后使用 Elasticsearch 的查詢語言來對文檔進行分詞匹配、相關性評分、高亮顯示等操作,返回相關度高的結果列表。
  • 日志分析:Elasticsearch 可以用來收集、存儲和分析海量的日志數據,如項目日志、Nginx log、MySQL Log 等,往往很難從繁雜的日志中獲取有價值的信息。Elasticsearch 能夠借助 Beats、Logstash 等工具快速對接各種常見的數據源,并通過集成的 Kibana 高效地完成日志的可視化分析,讓日志產生價值。
  • 運維監控:Elasticsearch 也可以用來監控和管理 IT 系統的運行狀態和性能指標,如 CPU、內存、磁盤、網絡等。可以使用 Beats、Logstash 將這些數據實時采集并索引到 Elasticsearch 中,然后通過 Kibana 構建自定義的儀表盤和告警規則,實現實時的運維監控和預警。
  • 數據可視化:Elasticsearch 與 Kibana 的結合提供了強大的數據可視化能力,可以使用 Kibana 來創建各種類型的圖表和儀表盤,展示 Elasticsearch 中存儲或聚合的數據,如直方圖、餅圖、地圖、時間線等。還可以使用 Kibana 的 Canvas 功能來制作動態的數據展示頁面,或者使用 Kibana 的 Lens 功能來進行交互式的數據探索。

waynboot-mall 商城選擇使用 Elasticsearch 作為搜索引擎,負責對商品數據進行索引和檢索,選擇 Elasticsearch 的原因有以下幾點:LFP28資訊網——每日最新資訊28at.com

  1. Elasticsearch 是一個開源的分布式搜索引擎,基于 Lucene 開發,支持全文檢索、結構化檢索、地理位置檢索等多種類型的檢索,功能豐富。
  2. Elasticsearch 本身具有高性能和高可用性的設計,可以通過集群和分片機制實現水平擴展,支持海量數據的存儲和處理,適合大規模的商城搜索場景。
  3. Elasticsearch 網上社區活躍,現有互聯網上有大量的使用文檔和案例,方便入門使用和問題排查。
  4. Elasticsearch 有眾多分詞器插件,關于中文分詞器的使用非常成熟,拿來即用,支持自定義字典等。

waynboot 項目使用的 Elasticsearch 插件

Elasticsearch 的插件非常豐富,我給大家介紹其中 waynboot 項目使用的 Elasticsearch 插件。LFP28資訊網——每日最新資訊28at.com

IK Analyzer

IK Analyzer 是一個開源的中文分詞器,由阿里巴巴集團發布。它采用了細粒度切分和歧義處理等技術,能夠較好地處理各種中文文本。IK Analyzer 支持普通模式、搜索模式和拼音模式三種分詞方式,并可以根據需要自定義字典。LFP28資訊網——每日最新資訊28at.com

Pinyin Analyzer

Pinyin Analyzer 插件是一個用于將中文字符轉換為拼音的插件,它集成了 NLP 工具(nlp-lang)。該插件包含了分析器:pinyin,分詞器:pinyin 和 token-filter:pinyin。該插件還提供了一些可選的參數,可以控制拼音的輸出格式,例如是否保留首字母,是否保留全拼,是否保留非中文字符等。LFP28資訊網——每日最新資訊28at.com

目錄結構

在 waynboot-mall 項目中,給 Elasticsearch 定義了專門的數據訪問層 waynboot-data-elastic,該層目錄結構如下:LFP28資訊網——每日最新資訊28at.com

|-- waynboot-data                    // 數據訪問層    |   |-- waynboot-data-elastic        // Elasticsearch訪問配置模塊    |       |-- config    |       |-- constant    |       |-- mananger

包目錄說明如下:LFP28資訊網——每日最新資訊28at.com

  • config:Elasticsearch 相關的配置類,包含 ElasticConfig 連接配置類 以及 ElasticClientConfig 客戶端配置相關類,ElasticClientConfig 類可以設置訪問密碼。
  • constants:Elasticsearch 訪問層的相關常量類,這里面定義了商品同步數據的索引名稱等信息。
  • mananger:Elasticsearch 訪問層的相關操作類,定義了 ElasticDocument 文檔操作類,用于操作 Elasticsearch。

代碼實戰

在 waynboot-mall 項目中,Elasticsearch 主要用于支持首頁商品的分詞搜索、分頁排序等功能。Elasticsearch 版本是 7.0,以下實戰講解都是在 7.0 版本基礎上進行。LFP28資訊網——每日最新資訊28at.com

要使用 Elasticsearch ik 分詞器進行中文分詞搜索,首先需要安裝相應的插件 elasticsearch-analysis-ik,然后在創建索引時指定使用中文分詞器作為字段的 analyzer 屬性。LFP28資訊網——每日最新資訊28at.com

在日常對 Elasticsearch 的操作中,我們可以通過 rest api 的方式進行操作。LFP28資訊網——每日最新資訊28at.com

Elasticsearch rest api 操作

如下我們可以創建一個索引名稱為 goods,包含兩個屬性 title、content。并且 這兩個屬性都使用 ik 分詞器。注意這里我用的 Elasticsearch 提供 Rest api 方式創建索引。LFP28資訊網——每日最新資訊28at.com

PUT /goods    {        "settings": {            "index": {                "number_of_shards": 1,                "number_of_replicas": 0            }        },        "mappings": {            "properties": {                "title": {                    "type": "text",                    "analyzer": "ik_max_word"                },                "content": {                    "type": "text",                    "analyzer": "ik_max_word"                }            }        }    }

創建索引后,就可以向索引中添加兩條數據,例如:LFP28資訊網——每日最新資訊28at.com

POST /books/_doc/1    {        "title": "格林童話",        "content": "這本書介紹了很多童話故事,有白雪公主、獅子王、美人魚等。"    }    POST /books/_doc/2    {        "title": "中國童話故事",        "content": "這本書介紹了很多中國童話故事。"    }

然后我們就可以使用 match 語法來進行中文分詞檢索,這里我查詢 goods 索引中,title 屬性是 "動畫" 的記錄。如下:LFP28資訊網——每日最新資訊28at.com

GET /books/_search    {        "query":{            "match":{                "title": "童話"            }        }    }

查詢結果如下:LFP28資訊網——每日最新資訊28at.com

{        "took": 0,        "timed_out": false,        "_shards": {            "total": 1,            "successful": 1,            "skipped": 0,            "failed": 0        },        "hits": {            "total": {                "value": 2,                "relation": "eq"            },            "max_score": 0.11190013,            "hits": [                {                    "_index": "books",                    "_type": "_doc",                    "_id": "1",                    "_score": 0.11190013,                    "_source": {                        "title": "格林童話",                        "content": "這本書介紹了很多童話故事,有白雪公主、獅子王、美人魚等。"                    }                },                {                    "_index": "books",                    "_type": "_doc",                    "_id": "2",                    "_score": 0.099543065,                    "_source": {                        "title": "中國童話故事",                        "content": "這本書介紹了很多中國童話故事。"                    }                }            ]        }    }

可以看到,查詢結果中匹配了標題包含“童話”的文檔,這說明 Elasticsearch 使用了中文分詞器對查詢字符串和文檔進行了分詞,并根據相關性得分返回了結果。LFP28資訊網——每日最新資訊28at.com

全文搜索以及篩選排序

在 waynboot-mall 項目中,商城首頁頂部提供了商品搜索欄,用戶可以輸入商品名稱搜索自己想要的商品,搜索結果展示后,還可以進行熱門、新品過濾以及價格、銷量等進行排序。LFP28資訊網——每日最新資訊28at.com

圖片圖片LFP28資訊網——每日最新資訊28at.com

可以看到搜索功能還是比較復雜的,在 waynboot-mall 項目中,這些邏輯全部在 Elasticsearch 內部進行處理,代碼如下:LFP28資訊網——每日最新資訊28at.com

@RestController    @AllArgsConstructor    @RequestMapping("search")    public class SearchController extends BaseController {        private IGoodsService iGoodsService;        private ElasticDocument elasticDocument;        @GetMapping("result")        public R result(SearchVO searchVO) throws IOException {            // 獲取篩選、排序條件            Long memberId = MobileSecurityUtils.getUserId();            String keyword = searchVO.getKeyword();            Boolean filterNew = searchVO.getFilterNew();            Boolean filterHot = searchVO.getFilterHot();            Boolean isNew = searchVO.getIsNew();            Boolean isHot = searchVO.getIsHot();            Boolean isPrice = searchVO.getIsPrice();            Boolean isSales = searchVO.getIsSales();            String orderBy = searchVO.getOrderBy();            SearchHistory searchHistory = new SearchHistory();            if (memberId != null && StringUtils.isNotEmpty(keyword)) {                searchHistory.setCreateTime(LocalDateTime.now());                searchHistory.setUserId(memberId);                searchHistory.setKeyword(keyword);            }            Page<SearchVO> page = getPage();            // 查詢包含關鍵字、已上架商品            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();            MatchQueryBuilder matchFiler = QueryBuilders.matchQuery("isOnSale", true);            MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("name", keyword);            MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("keyword", keyword);            boolQueryBuilder.filter(matchFiler).should(matchQuery).should(matchPhraseQueryBuilder).minimumShouldMatch(1);            searchSourceBuilder.timeout(new TimeValue(10, TimeUnit.SECONDS));            // 按是否新品排序            if (isNew) {                searchSourceBuilder.sort(new FieldSortBuilder("isNew").order(SortOrder.DESC));            }            // 按是否熱品排序            if (isHot) {                searchSourceBuilder.sort(new FieldSortBuilder("isHot").order(SortOrder.DESC));            }            // 按價格高低排序            if (isPrice) {                searchSourceBuilder.sort(new FieldSortBuilder("retailPrice").order("asc".equals(orderBy) ? SortOrder.ASC : SortOrder.DESC));            }            // 按銷量排序            if (isSales) {                searchSourceBuilder.sort(new FieldSortBuilder("sales").order(SortOrder.DESC));            }            // 篩選新品            if (filterNew) {                MatchQueryBuilder filterQuery = QueryBuilders.matchQuery("isNew", true);                boolQueryBuilder.filter(filterQuery);            }            // 篩選熱品            if (filterHot) {                MatchQueryBuilder filterQuery = QueryBuilders.matchQuery("isHot", true);                boolQueryBuilder.filter(filterQuery);            }            // 組裝Elasticsearch查詢條件            searchSourceBuilder.query(boolQueryBuilder);            // Elasticsearch分頁相關            searchSourceBuilder.from((int) (page.getCurrent() - 1) * (int) page.getSize());            searchSourceBuilder.size((int) page.getSize());            // 執行Elasticsearch查詢            List<JSONObject> list = elasticDocument.search("goods", searchSourceBuilder, JSONObject.class);            List<Integer> goodsIdList = list.stream().map(jsonObject -> (Integer) jsonObject.get("id")).collect(Collectors.toList());            if (goodsIdList.isEmpty()) {                return R.success().add("goods", Collections.emptyList());            }            // 根據Elasticsearch中返回商品ID查詢商品詳情并保持es中的排序            List<Goods> goodsList = iGoodsService.searchResult(goodsIdList);            Map<Integer, Goods> goodsMap = goodsList.stream().collect(Collectors.toMap(goods -> Math.toIntExact(goods.getId()), o -> o));            List<Goods> returnGoodsList = new ArrayList<>(goodsList.size());            for (Integer goodsId : goodsIdList) {                returnGoodsList.add(goodsMap.get(goodsId));            }            if (CollectionUtils.isNotEmpty(goodsList)) {                AsyncManager.me().execute(new TimerTask() {                    @Override                    public void run() {                        searchHistory.setHasGoods(true);                        iSearchHistoryService.save(searchHistory);                    }                });            }            return R.success().add("goods", returnGoodsList);        }    }

這里對上面商城的搜索代碼給大家做一個講解:LFP28資訊網——每日最新資訊28at.com

  • 第一步:獲取篩選、排序條件
  • 第二步:獲取查詢條件-用戶搜索關鍵字、商品已上架
  • 第三步:獲取排序條件-按是否新品排序、按是否熱品排序、按價格高低排序、按銷量排序
  • 第四步:獲取過濾條件-篩選新品、篩選熱品
  • 第五步:組裝 Elasticsearch 查詢條件以及分頁條件
  • 第六步:執行 Elasticsearch 查詢操作
  • 第七步:獲取 Elasticsearch 中返回的商品 ID ,并根據商品 id 查詢商品詳情,最后商品保持 es 中的排序

總結一下

本文給大家講解了 waynboot-mall 項目中對于 elasticsearch 的使用以及代碼實戰講解。希望能幫助大家更好理解 elasticsearch,大家在自己的項目中如果要引入 elasticsearch,可以直接參照本文的示例代碼即可使用。LFP28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-75299-0.htmlElasticsearch使用實戰以及代碼詳解

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: MediatR讓進程內通信如此簡單,基于MediatR實現事件訂閱發布功能

下一篇: Python中容易被忽視的核心功能

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 神木县| 阜城县| 象山县| 前郭尔| 屏南县| 鹤壁市| 高邮市| 莱州市| 买车| 汉源县| 呼玛县| 乌海市| 吉首市| 开原市| 株洲县| 会东县| 克什克腾旗| 五华县| 宜川县| 密云县| 阿城市| 建平县| 德清县| 广昌县| 龙陵县| 瓮安县| 吉隆县| 南投县| 阿合奇县| 临漳县| 手游| 海原县| 凌云县| 应城市| 繁昌县| 永善县| 集安市| 汝阳县| 高雄市| 临澧县| 拉孜县|