ES分詞搜索

ES的使用

    • 前言
      • 作者使用的版本
      • 作者需求
    • 簡介
      • ES簡略介紹
      • ik分詞器簡介
    • 使用
      • es的直接簡單使用
        • es的查詢
      • es在java中使用
      • 備注說明

前言

作者使用的版本

  • es: 7.17.27
  • spring-boot-starter-data-elasticsearch: 7.14.2

作者需求

作者接到一個業務需求,我們系統有份數據被用來查詢,進行搜索改造。我們的數據是可以分為兩層,第一層是物品,物品含有物品名和物品別名。第二層是規格型號,一個物品可以配置多個規格型號,同一物品不同規格型號有不同的價格。
原先的搜索只支持對物品名或別名的模糊搜索。將帶出該物品下所有的規格列表被用來選擇。比如說原來數據庫里有個物品叫做 蒙古大馬,如果使用蒙古的大馬進行搜索時搜索不到的,需要對這種搜索進行支持。
于是,作者選用了es作為文本搜索。作者只達到了可用的效果,并沒有深究es的文檔。底部會放置文檔鏈接。
如上所述,本文并不對es做詳細介紹。在上面說明中,作者已經碰到了問題,而es可以解決這個問題,所以本文只大概講述es為什么能夠解決我的問題以及我如何使用es解決問題

簡介

ES簡略介紹

es為什么能夠解決我的問題,我想要的搜索場景是,可以從用戶輸入的文本串中提取出有用的匹配信息,然后到我的數據庫中對待匹配的信息進行匹配。命中即認為該數據是用戶需要的,用戶輸入文本可能與數據庫中的某段信息的文字部分是完全一致的,但是文字順序是被打亂的。mysql數據庫支持like,所以可以將用戶輸入文字串分割成每個字,然后用or去拼接查詢。這種查詢效率和使用方式可想而知有多么恐怖。但是es不需要這么麻煩的使用姿勢,es支持match,可以對文本進行匹配搜索。為什么MySQL這么麻煩,而es看起來很方便呢?因為他們主要的應用場景就不同,所以底層的數據結構就不同。首先看看他們對數據的索引方式:
MySQL的索引方式很簡單,一條記錄留存,如果指定了需要索引某個字段,就會將這個字段的對應記錄的ID拿出來,存儲到B+樹中,二分搜索可以對有序數據進行快速查找,但是如果使用like '%x%';可以看到無法判斷要匹配文本的首字母了,也就是無法使用索引了,這樣數據量一旦上來,查詢效率會飛快下降。
es的索引方式中文一直叫做倒排索引,什么叫倒排索引,在mysql中,索引的是這個字段的全文本,然后用全文本去匹配我們的輸入,如果匹配不到就錯了,換個數據繼續匹配。這個思路就是,我們需要所有數據的全文本,然后挨個匹配。可現在的場景是需要這么做,你只需要給我輸入的文本內有效部分的有關數據即可。所以我們首先需要考慮將輸入信息進行分割提取。然后用提取出來的每部分數據參與匹配。那有個想法,如果我存的數據,也按照這種分割-提取來提前建立一份索引呢?那就可以用提取到的部分輸入直接去匹配數據庫里提前存儲好的數據的索引。匹配到一個部分即認為命中,匹配到多個部分認為相關度更高,最終得分也就越高。這種將文檔的文本打散進行索引再反過來查詢文檔的,被稱作倒排索引

ik分詞器簡介

既然有個數據庫可以支持倒排索引,那么接下來就看看怎么對文本分詞,首先一個問題是為什么要分詞,如果不分詞,我輸入一段話,每個字都是一個token。那如果我認為有些字按照一定的順序組合起來有固定的含義,他們就成了詞,詞就意味著通用,我們在存儲和使用時都會按照這個順序。即他們也可以做token。這樣一份文檔的token數量就會減少,這樣可以顯著提升查詢的效率。
但是這也有個問題,比如上文的內蒙大馬。如果我用了分詞器,ik的通用詞庫里有蒙古、大馬,我現在用去搜索,命中結果集為空,因為這段文本被索引為蒙古大馬,你用是匹配不到大馬這個索引的。字是默認組詞使用的,如果有單字也是可以用使用的特殊情況,可以在詞典里添加這個單字,需要注意詞的順序,最短的詞放在上面,否則由于分詞器是不貪心的,已經匹配了一個比較好的索引,就不去再考慮生成一個差的索引了。詞典添加后還要注意不要使用ik_smart類型的分析器,下文會有說明。如果你認為你的場景每個字都需要考慮,那就簡單了,不要分詞,以改兼賑、兩難自解;

es本身不支持中文分詞,ik分詞器可以支持中文的分詞,所以需要ik分詞器。ik分詞有兩種type:
ik_smart:對文本進行粗粒度分詞,比如藍瘦香菇這個詞,我如果詞典里有藍瘦香菇藍瘦香菇。他的分詞結果藍瘦香菇;顯然,他的索引數量會更少,也會丟掉更多數據的查詢。
在這里插入圖片描述

ik_max_word,進行最粗粒度的分詞,會列舉所有的可能(但不包括已經被組詞的字,所以單字的特殊情況可以將它作為詞來解決)。
在這里插入圖片描述
每次更新詞庫都需要重啟,這太費勁了,還好ik支持熱更新詞庫。只需要在配置文件配置remote_ext_dict即可。但是,更新詞典后只對之后的新數據有效,舊有數據需要重建索引

使用

es的直接簡單使用

  • 創建索引
PUT /index_name
{"mappings": {"properties": {"ref_id": { "type": "long" },"ref_type": { "type": "integer" },"goods_name": { "type": "text","analyzer":"my_ik_analyzer","search_analyzer":"ik_max_word"},"param_value": { "type": "text","analyzer":"my_ik_analyzer","search_analyzer":"ik_max_word"}}}
}
  • 刪除索引
DELETE /index_name
  • 新增或更新文檔
POST /index_name/_doc/doc_id # 最后一位參數可以指定生成的文檔ID
{
"ref_id": 1,
"ref_type":1,
"goods_name": "狗;犬;野狗;導盲犬",
"param_value": "中華田園犬;美國狗;吃狗糧;奧利給"
}
  • 分析測試
POST /index_name/_analyze?pretty
{
"analyzer": "ik_max_word", 
"text":"內蒙大馬"
}
  • 查詢
POST /bws_price_library/_search?pretty
{"query":
{"bool":{"must": [{  "multi_match": {"query":"大馬","fields":["goods_name^2","param_value"]  #字段名后面的^n可以指定得分權重。}},{"term":{"ref_type":"101"}}]}
}}
es的查詢

es的查詢很負責,所以能覆蓋非常多的場景。作者上面涉及 準確查詢term、匹配查詢match,多字段匹配查詢multi_match、布爾嵌套查詢bool,只做了簡單的示例,很容易觸類旁通。具體的使用方式作者有時間會慢慢補充。

es在java中使用

  • 保存
XXXXIndex index = new XXXXIndex();index.setId(BwsPriceConstant.SPECS_REF_TYPE_PART+"_"+id);index.setRefId(id);index.setRefType(BwsPriceConstant.SPECS_FEE_TYPE_PART);index.setGoodsName("name");index.setParamValue("value");IndexCoordinates indexCoordinates = elasticsearchRestTemplate.getIndexCoordinatesFor(XXXXIndex.class);elasticsearchRestTemplate.save(index,indexCoordinates);
  • 刪除
elasticsearchRestTemplate.delete(id, XXXXIndex.class);
  • 更新
            IndexCoordinates indexCoordinates = elasticsearchRestTemplate.getIndexCoordinatesFor(XXXXIndex.class);Document document = Document.create();document.setId(index.getId());document.putIfAbsent("ref_id",index.getRefId());document.putIfAbsent("ref_type",index.getRefType());document.putIfAbsent("goods_name",index.getGoodsName());document.putIfAbsent("param_value",index.getParamValue());elasticsearchRestTemplate.update(UpdateQuery.builder(index.getId()).withDocument(document).build(),indexCoordinates);
  • 查詢
       Pageable pageable = PageRequest.of(reqVo.getCurrentPage()-1, reqVo.getPageSize());Map<String, Float> fields = new HashMap<>();fields.put("goods_name",3.0f);fields.put("param_value",1.0f);// 查詢實體使用構造器模式,multiMatchQuery.fields方法可以指定查詢權重,查看構造方法可以看到默認是都給了1的權重。這個權重也可以在構建索引的時候指定,不過查詢時指定的話會更靈活一些NativeSearchQuery build = new NativeSearchQueryBuilder().withPageable(pageable).withQuery(new BoolQueryBuilder().must(new TermQueryBuilder("ref_type", reqVo.getFeeType())).must(QueryBuilders.multiMatchQuery(reqVo.getName(), "goods_name", "param_value").fields(fields))).build();SearchHits<XXXXIndex> search = elasticsearchRestTemplate.search(build, XXXXIndex.class);List<SearchHit<XXXXIndex>> searchHits = search.getSearchHits();// SearchHit中的Content就是指定的類型對象

備注說明

在使用時建議做好數據的手動同步,以防萬一

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82996.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82996.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82996.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Axure設計案例——科技感立體柱狀圖

想讓你的數據展示告別平淡無奇&#xff0c;成為吸引全場目光的焦點嗎&#xff1f;快來瞧瞧這個Axure設計的科技感立體柱狀圖案例&#xff01;科技感設計風格借助逼真的立體效果打破傳統柱狀圖的平面感&#xff0c;營造出一種令人眼前一亮的視覺震撼。每一個柱狀體都仿佛是真實存…

惡意npm與VS Code包竊取數據及加密貨幣資產

60個npm包竊取系統敏感信息 安全研究人員在npm軟件包注冊表中發現60個惡意組件&#xff0c;這些組件能夠收集主機名、IP地址、DNS服務器和用戶目錄信息&#xff0c;并將其發送至Discord平臺控制的終端節點。據Socket安全研究員Kirill Boychenko上周發布的報告顯示&#xff0c;…

leetcode 2359. 找到離給定兩個節點最近的節點

給你一個 n 個節點的 有向圖 &#xff0c;節點編號為 0 到 n - 1 &#xff0c;每個節點 至多 有一條出邊。 有向圖用大小為 n 下標從 0 開始的數組 edges 表示&#xff0c;表示節點 i 有一條有向邊指向 edges[i] 。如果節點 i 沒有出邊&#xff0c;那么 edges[i] -1 。 同時…

1. pytorch手寫數字預測

1. pytorch手寫數字預測 1.背景2.準備數據集2.定義模型3.dataloader和訓練4.訓練模型5.測試模型6.保存模型 1.背景 因為自身的研究方向是多模態目標跟蹤&#xff0c;突然對其他的視覺方向產生了興趣&#xff0c;所以心血來潮的回到最經典的視覺任務手寫數字預測上來&#xff0…

AWS WebRTC:獲取ICE服務地址(part 2): ICE Agent的作用

上一篇&#xff0c;已經獲取到了ICE服務地址&#xff0c;從返回結果中看&#xff0c;是兩組TURN服務地址。 拿到這些地址有什么用呢&#xff1f;接下來就要說到WebRTC中ICE Agent的作用了&#xff0c;返回的服務地址會傳給WebRTC最終給到ICE Agent。 ICE Agent的作用&#xf…

大數據時代的利劍:Bright Data網頁抓取與自動化工具共建高效數據采集新生態

目錄 一、為何要選用Bright Data網頁自動化抓取——幫助我們高效高質解決以下問題&#xff01; 二、Bright Data網頁抓取工具 - 網頁爬蟲工具實測 2.1 首先注冊用戶 2.2 首先點擊 Proxies & Scraping &#xff0c;再點擊瀏覽器API的開始使用 2.3 填寫通道名稱&#xff…

指紋識別+精準化POC攻擊

開發目的 解決漏洞掃描器的痛點 第一就是掃描量太大&#xff0c;對一個站點掃描了大量的無用 POC&#xff0c;浪費時間 指紋識別后還需要根據對應的指紋去進行 payload 掃描&#xff0c;非常的麻煩 開發思路 我們的思路分為大體分為指紋POC掃描 所以思路大概從這幾個方面…

【Day40】

DAY 40 訓練和測試的規范寫法 知識點回顧&#xff1a; 彩色和灰度圖片測試和訓練的規范寫法&#xff1a;封裝在函數中展平操作&#xff1a;除第一個維度batchsize外全部展平dropout操作&#xff1a;訓練階段隨機丟棄神經元&#xff0c;測試階段eval模式關閉dropout 作業&#x…

【HTML-13】HTML表格合并技術詳解:打造專業數據展示

表格是HTML中展示結構化數據的重要元素&#xff0c;而表格合并則是提升表格表現力的關鍵技術。本文將全面介紹HTML中的表格合并方法&#xff0c;幫助您創建更專業、更靈活的數據展示界面。 1. 表格合并基礎概念 在HTML中&#xff0c;表格合并主要通過兩個屬性實現&#xff1a…

<uniapp><threejs>在uniapp中,怎么使用threejs來顯示3D圖形?

前言 本專欄是基于uniapp實現手機端各種小功能的程序,并且基于各種通訊協議如http、websocekt等,實現手機端作為客戶端(或者是手持機、PDA等),與服務端進行數據通訊的實例開發。 發文平臺 CSDN 環境配置 系統:windows 平臺:visual studio code、HBuilderX(uniapp開…

如何制作全景VR圖?

全景VR圖&#xff0c;特別是720度全景VR&#xff0c;為觀眾提供一種沉浸式體驗。 全景VR圖能夠捕捉場景的全貌&#xff0c;還能將多個角度的圖片或視頻無縫拼接成一個完整的全景視角&#xff0c;讓觀眾在虛擬環境中自由探索。隨著虛擬現實&#xff08;VR&#xff09;技術的飛速…

前端使用qrcode來生成二維碼的時候中間添加logo圖標

這個開源倉庫可以讓你在前端頁面中生成二維碼圖片&#xff0c;并且支持調整前景色和背景色&#xff0c;但是有個問題&#xff0c;就是不能添加logo圖片。issue&#xff1a; GitHub Where software is built 但是已經有解決方案了&#xff1a; add a logo picture Issue #21…

【C語言】函數指針及其應用

目錄 1.1 函數指針的概念和應用 1.2 賦值與內存模型 1.3 調用方式與注意事項 二、函數指針的使用 2.1 函數指針的定義和訪問 2.2 動態調度&#xff1a;用戶輸入驅動函數執行 2.3 函數指針數組進階應用 2.4 函數作為參數的高階抽象 三、回調函數 3.1 指針函數…

安裝flash-attention失敗的終極解決方案(WINDOWS環境)

想要看linux版本下安裝問題的請走這里&#xff1a;安裝flash-attention失敗的終極解決方案&#xff08;LINUX環境&#xff09; 其實&#xff0c;現在的flash-attention不像 v2.3.2之前的版本&#xff0c;基本上不兼容WINDOWS環境。但是在WINDOWS環境安裝總還是有那么一點不順暢…

[C]基礎16.數據在內存中的存儲

博客主頁&#xff1a;向不悔本篇專欄&#xff1a;[C]您的支持&#xff0c;是我的創作動力。 文章目錄 0、總結1、整數在內存中的存儲1.1 整數的二進制表示方法1.2 不同整數的表示方法1.3 內存中存儲的是補碼 2、大小端字節序和字節序判斷2.1 什么是大小端2.2 為什么有大小端2.3…

Python 基于卷積神經網絡手寫數字識別

Ubuntu系統&#xff1a;22.04 python版本&#xff1a;3.9 安裝依賴庫&#xff1a; pip install tensorflow2.13 matplotlib numpy -i https://mirrors.aliyun.com/pypi/simple 代碼實現&#xff1a; import tensorflow as tf from tensorflow.keras.models import Sequent…

ElectronBot復刻-電路測試篇

typec-16p 接口部分 USB1&#xff08;Type - C 接口&#xff09;&#xff1a;這是通用的 USB Type - C 接口&#xff0c;具備供電和數據傳輸功能。 GND 引腳&#xff08;如 A1、A12、B1、B12 等&#xff09;&#xff1a;接地引腳&#xff0c;用于提供電路的參考電位&#xff0…

ESP8266+STM32 AT驅動程序,心知天氣API 記錄時間: 2025年5月26日13:24:11

接線為 串口2 接入ESP8266 esp8266.c #include "stm32f10x.h"//8266預處理文件 #include "esp8266.h"//硬件驅動 #include "delay.h" #include "usart.h"//用得到的庫 #include <string.h> #include <stdio.h> #include …

CDN安全加速:HTTPS加密最佳配置方案

CDN安全加速的HTTPS加密最佳配置方案需從證書管理、協議優化、安全策略到性能調優進行全鏈路設計&#xff0c;以下是核心實施步驟與注意事項&#xff1a; ??一、證書配置與管理?? ??證書選擇與格式?? ??證書類型??&#xff1a;優先使用受信任CA機構頒發的DV/OV/EV證…

【前端】Twemoji(Twitter Emoji)

目錄 注意使用Vue / React 項目 驗證 Twemoji 的作用&#xff1a; Twemoji 會把你網頁/應用中的 Emoji 字符&#xff08;如 &#x1f604;&#xff09;自動替換為 Twitter 風格的圖片&#xff08;SVG/PNG&#xff09;&#xff1b; 它不依賴系統字體&#xff0c;因此在 Android、…