全文搜索引擎技術詳解Apache Solr的使用

      網友投稿 820 2022-05-29

      Solr

      Solr是一個可擴展的,可部署,搜索,存儲引擎,優化搜索大量以文本為中心的數據庫

      Solr是開源搜索平臺,用于構建搜索應用程序

      建立在Lucene(全文搜索引擎)之上

      Solr是企業級的,快速的和高度可擴展的,使用Solr構建的應用程序可以提供高性能,但是非常復雜

      Solr可以和Hadoop一起使用:由于Hadoop處理大量數據,Solr可以從大的數據源中找到所需信息.

      Solr不僅限于搜索,也可以用于存儲.和其它NoSQL數據庫一樣,是一種非關系數據存儲和處理技術

      Apache Solr特點

      Solr是Lucene的Java API包裝,使用Solr,就可以使用Lucene的所有功能

      RESTful API: 要與Solr通信,可以使用RESTful服務與Solr通信,可以使用XML,JSON,CSV等格式的文件作為輸入文檔,并以相同的文件格式獲取結果

      全文搜索: Solr提供了全文搜索所需的所有功能:令牌,短語,拼寫檢查,通配符,自動完成

      企業準備: 根據企業或組織的需要,Solr可以部署在任何類型的系統:獨立,分布式,云

      靈活可擴展: 通過擴展Java類并進行相關配置,可以定制Solr組件

      NoSQL數據庫: Solr可以用作大數量級的NoSQL數據庫,可以沿著集群分布搜索任務

      搜索引擎

      搜索引擎:

      搜索引擎是龐大的互聯網資源數據庫,如網頁,新聞組,程序,圖像等

      有助于在網上定位信息

      用戶可以通過以關鍵字或短語的形式將查詢傳遞到搜索引擎中來搜索信息,然后搜索引擎搜索其數據庫并向用戶返回相關鏈接

      搜索引擎組件

      搜索引擎有三個組件:

      Web爬蟲: 一個收集網絡信息的軟件組件

      數據庫: Web上的所有信息都存儲在數據庫中,包含大量的Web資源

      搜索接口: 這個組件是用戶和數據庫之間的接口,幫助用戶搜索數據庫

      搜索引擎工作流程

      全文搜索引擎技術詳解之Apache Solr的使用

      獲取原始內容: 任何搜索應用程序的第一步是收集要進行搜索的目標內容

      構建文檔: 從原始內容構建文檔,讓搜索應用程序可以很容易的理解和解釋

      分析文檔: 在索引開始之前,將對文檔進行分析

      索引文檔: 當文檔被構建和分析后,下一步是對文檔建立索引,以便可以基于特定鍵而不是文檔的全部內容來檢索該文檔.索引類似于在書開始頁或末尾處的目錄索引,其中常見單詞以頁碼顯示,使得這些單詞可以快速追蹤,而不是搜索整本書

      用于搜索的用戶接口: 當索引數據庫就緒,應用程序就可以執行搜索操作.為了幫助用戶進行搜索,應用必須提供用戶接口,用戶可以在用戶接口中輸入文本并啟動搜索過程

      構建查詢: 當用戶做出搜索文本的請求,應用程序應該使用該文本準備查詢對象,然后可以使該查詢對象來查詢索引數據庫以獲得相關細節

      搜索查詢: 使用查詢對象,檢查索引數據庫以獲取相關詳細信息和內容文檔

      渲染結果: 當收到所需結果,應用程序應決定如何使用用戶界面向用戶顯示搜索結果

      分詞技術

      分詞技術: 搜索引擎針對用戶提交查詢的關鍵詞串進行的查詢處理后,根據用戶的關鍵詞串用各種匹配方法進行分詞的一種技術

      中文分詞算法

      基于字符串匹配:

      即掃描字符串,如果發現字符串的子串和詞相同,就算匹配

      這類分詞通常會加入一些啟發式規則:正向/反向最大匹配,長詞優先等

      基于字符串匹配算法優點:

      速度快

      都是O(n)時間復雜度

      實現簡單

      效果尚可

      基于字符串匹配算法缺點:

      對歧義和未登錄詞處理不好

      ikanalyzer,paoding等就是基于字符串匹配的分詞

      基于統計及機器學習的分詞方式:

      基于人工標注的詞性和統計特征,對中文進行建模. 即根據觀測到的數據(標注好的語料)對模型參數進行估計.即 訓練

      在分詞階段再通過模型計算各種分詞出現的概率,將概率最大的分詞結果作為最終結果

      常見的序列標注模型:HMM,CRF

      基于統計及機器學習的分詞方式優點:

      可以很好地處理歧義和未登錄問題

      效果比基于字符串匹配算法更好

      基于統計及機器學習的分詞方式缺點:

      需要大量的人工標注數據

      較慢的分詞速度

      IKAnalyzer

      IKAnalyzer是一個開源的,基于Java語言開發的輕量級中文分詞工具包

      基于文本匹配,不需要投入大量的人力進行訓練和標注

      可以自定詞典,方便加入特定領域的詞語,能分出多粒度的結果

      部署Solr并安裝IKAnalyzer

      創建/usr/local/docker/solr/ikanalyzer目錄

      /usr/local/docker/solr 用于存放docker-compose.yml配置文件 /usr/local/docker/solr/ikanalyzer 用于存放Dockerfile鏡像配置文件

      docker-compose.yml

      version: '3.1' services: solr: build: ikanalyzer restart: always container_name: solr ports: - 8983:8983 volumes: - ./solrdata:/opt/solrdata

      Dockerfile(在/usr/local/docker/solr/ikanalyzer中需要有文件:ik-analyzer-solr5-5.x.jar,solr-analyzer-ik-5.1.0.jar,ext.dic,stopword.dic,IKAnalyzer.cfg.xml,managed-schema)

      FROM solr # 創建Core WORKDIR /opt/solr/server/solr RUN mkdir ik_core WORKDIR /opt/solr/server/solr/ik_core RUN echo 'name=ik_core' > core.properties RUN mkdir data RUN cp -r ../configsets/sample_techproducts_configs/conf/ . # 安裝中文分詞 WORKDIR /opt/solr/server/solr-webapp/webapp/WEB-INF/lib ADD ik-analyzer-solr5-5.x.jar . ADD solr-analyzer-ik-5.1.0.jar . WORKDIR /opt/solr/server/solr-webapp/webapp/WEB-INF ADD ext.dic . ADD stopword.dic . ADD IKAnalyzer.cfg.xml . # 增加分詞配置 COPY managed-schema /opt/solr/server/solr/ik_core/conf WORKDIR /opt/solr

      構建鏡像: 在/usr/local/docker/solr中執行命令

      docker-compose up -d

      Solr分析功能

      修改managed-schema配置業務系統字段

      Solr中自帶的相同字段無需再添加,其它字段需要手動添加Solr字段(通過編輯managed-schema配置文件來手動添加Solr字段)

      復制配置到容器

      docker cp managed-schema solr:/opt/solr/server/solr/ik_core/conf

      重啟容器

      docker-compose restart

      在Solr的Web界面可以進行CRUD操作

      SpringBoot整合Solr

      創建搜索服務接口

      創建myshop-service-search-api項目,該項目只負責定義定義接口

      pom.xml

      4.0.0 com.funtl myshop-dependencies 1.0.0-SNAPSHOT ../myshop-dependencies/pom.xml myshop-service-search-api jar

      在項目中創建SearchService接口

      package com.oxford.myshop.service.search.api; public interface SearchService { List search(String query,int page,int rows); }

      創建TbItemResult用于返回Solr結果集

      package com.oxford.myshop.service.search.domain; import java.io.Serializable; public class TbItemResult implements Serializable { private long id; private long tbTtemCid; private String tbItemCname; private String tbItemTitle; private String tbItemSellPoint; private String tbItemDesc; public long getId(){ return id; } public void setId(long id){ this.id=id; } public long getTbTtemCid(){ return tbTtemCid; } public void setTbTtemCid(long tbTtemCid){ this.tbTtemCid=tbTtemCid; } public String getTbItemCname(){ return tbItemCname; } public void setTbItemCname(String tbItemCname){ this.tbItemCname=tbItemCname; } public String getTbItemTitle(){ return tbItemTitle; } public void setTbItemTitle(String tbItemTitle){ this.tbItemTitle=tbItemTitle; } public String getTbItemSellPoint(){ return tbItemSellPoint; } public void setTbItemSellPoint(String tbItemSellPoint){ this.tbItemSellPoint=tbItemSellPoint; } public String getTbItemDesc(){ return tbItemDesc; } public void setTbItemDesc(String tbItemDesc){ this.tbItemDesc=tbItemDesc; } }

      創建搜索服務提供者

      創建myshop-service-search-provider服務提供者項目

      MyShopServiceSearchProviderApplication

      package com.oxford.myshop.service.search.provider; @EnableHystrix @EnableHystrixDashboard @SpringBootApplication(scanBasePackages="com.oxfrod.myshop") @MapperScan(basePackages="com.oxford.myshop.service.search.provider.mapper") public class MyShopServiceSearchProviderApplication { public static void main(String[] args) { SpringApplication.run(MyShopServiceSearchProviderApplication.class,args); Main.main(args); } }

      在項目中創建TbItemResultMapper接口用于查詢MySQL中的數據,用于插入到Solr數據庫中

      package com.oxford.myshop.service.search.provider.mapper; @Respository public interface TbItemResultMapper { List selectAll(); }

      Spring的四大注解: 1. @Controller 2. @Service 3. @Component 4. @Repository

      在resource中創建mapper包用于創建TbContentCategoryMapper.xml

      初始化Solr: public void initSolr() { List tbItemResult=tbItemResultMapper.selectAll(); try{ SolrInputDocument document=null; for(TbItemResult tbItemResult:tbItemResults){ document=new SolrInputDocument(); document.addFiled("id",tbItemResult.getId()); document.addFiled("tb_item_cid",tbItemResult.getTbItemCid()); document.addFiled("tb_item_cname",tbItemResult.getTbItemCname()); document.addFiled("tb_item_title",tbItemResult.getTbItemTitle()); document.addFiled("tb_item_sell_point",tbItemResult.getTbItemSellPoint()); document.addFiled("tb_item_desc",tbItemResult.getTbItemDesc()); solrClient.add(document); solrClient.commit(); } }catch(SolrServerException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } } --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 搜索Solr: public void searchSolr(){ SolrQuery query=new SolrQuery(); // 設置查詢條件 query.setQuery("手機"); // 分頁查詢 query.setStart(0); query.setRows(10); // 設置查詢的默認域 query.set("df","tb_item_keywords"); // 設置高亮顯示 query.setHighlight(true); query.addHighlightField("tb_item_title"); query.setHighlightSimplePre(""); query.setHighlightSimplePost(""); // 開始查詢 try{ QueryResponse queryResponse=solrClient.query(query); SolrDocumentList results=queryResponse.getResults(); // 獲取高亮 Map>> highlighting=queryResponse.getHighlighting(); for(SolrDocument result:results){ List strings=highlighting.get(result.get("id")).get(result.get("tb_item_title")) if(strings!=null&&strings.size()>0){ String title=strings.get(0); System.out.println(title); } } }catch(SolrServerException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } }

      創建SearchServiceImpl實現SearchService接口

      package com.oxford.myshop.service.search.provider.api.impl; @Service(version="${services.versions.search.v1}") public class SearchServiceImpl implements SearchService{ @Autowired private SolrClient solrClient; @Override public List search(String query,int page,int rows){ List searchResults=Lists.newArrayList(); SolrQuery query=new SolrQuery(); // 設置查詢條件 query.setQuery("手機"); // 分頁查詢 query.setStart((page-1)*rows); query.setRows(rows); // 設置查詢的默認域 query.set("df","tb_item_keywords"); // 設置高亮顯示 query.setHighlight(true); query.addHighlightField("tb_item_title"); query.setHighlightSimplePre(""); query.setHighlightSimplePost(""); // 開始查詢 try{ QueryResponse queryResponse=solrClient.query(query); SolrDocumentList results=queryResponse.getResults(); // 獲取高亮 Map>> highlighting=queryResponse.getHighlighting(); for(SolrDocument solrDocument:solrDocuments){ TbItemResult result=new TbResult(); result.setId(Long.parseLong(String.valueOf(solrDocument.get("id")))); result.setTbItemCid(Long.parseLong(String.valueOf(solrDocument.get("tb_item_cid")))); result.setTbItemCname((String)solrDocument.get("tb_item_cname")); result.setTbItemTitle((String)solrDocument.get("tb_item_title")); result.setTbItemSellPoint((String)solrDocument.get("tb_item_sell_point")); result.setTbItemDesc((String)solrDocument.get("tb_item_desc")); String tbItemTitle=""; List list=highlighting.get(result.get("id")).get(result.get("tb_item_title")) if(list!=null&&lsit.size()>0){ String title=list.get(0); }else{ tbItemTitle=(String)solrDocument.get("tb_item_title"); } result.setTbItemTitle(tbItemTitle); searchResults.add(result); } }catch(SolrServerException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } return searchResults; } }

      創建搜索服務消費者

      創建搜索服務消費者myshop-service-search-consumer對Solr數據庫中的數據進行檢索

      MyShopServiceSearchConsumerApplication

      package com.oxford.myshop.service.search.consumer; @EnableHystrix @EnableHystrixDashboard @SpringBootApplication(scanBasePackages="com.oxford.myshop",exclude=DataSourceAutoConfiguration.class) public class MyShopServiceSearchConsumerApplication{ public static void main(String[] args){ SpringApplication.run(MyShopServiceSearchConsumerApplication.class,args); Main.main(args); } }

      SearchController

      package com.oxford.myshop.service.search.consumer.controller; @RestController public class SearchController{ @Reference(version="${services.versions.search.v1}") private SearchService searchService; @RequestMapping(value="search/{query}/{page}/{rows}",method=RequestMethod.GET) public List search( @PathVariable(required=true) String query, @PathVariable(required=true) int page, @PathVariable(required=true) int rows ){ return searchService.search(query,page,rows) } }

      Apache Lucene/Solr 搜索引擎 數據庫

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Android 程序崩潰之快速鎖定!
      下一篇:把設備分享給每個Docker Container
      相關文章
      亚洲AV无码国产丝袜在线观看| 久久精品国产亚洲Aⅴ香蕉| 国产亚洲成AV人片在线观黄桃| xvideos亚洲永久网址| 亚洲精品第一国产综合亚AV| 国产AV旡码专区亚洲AV苍井空| 最新亚洲卡一卡二卡三新区| 亚洲高清有码中文字| 亚洲www77777| 亚洲人成欧美中文字幕| 亚洲人成网站免费播放| 亚洲AV无码AV日韩AV网站| 亚洲AV综合色区无码一二三区 | 日韩va亚洲va欧洲va国产| 国产亚洲av片在线观看播放| 国产AV无码专区亚洲AVJULIA| 国产亚洲一区二区精品| 亚洲AV午夜成人影院老师机影院 | 亚洲国产精华液网站w| 精品亚洲综合久久中文字幕| 久久亚洲一区二区| 亚洲人成在线影院| 亚洲成人高清在线观看| 亚洲另类古典武侠| 亚洲一区二区无码偷拍| 亚洲av综合日韩| 亚洲区不卡顿区在线观看| 亚洲午夜福利AV一区二区无码| 国产成人亚洲综合无码精品| 色播亚洲视频在线观看| 亚洲人6666成人观看| 亚洲一区二区无码偷拍| 亚洲M码 欧洲S码SSS222| 精品亚洲视频在线观看| 亚洲AV无码久久精品色欲| 亚洲美女视频一区二区三区| 亚洲91精品麻豆国产系列在线| 亚洲男同gay片| 亚洲乱码中文字幕综合234| 久久精品国产亚洲一区二区| 99久久亚洲精品无码毛片|