根據文檔建立索引,再對索引進行查詢獲取文檔。java
相比與順序查詢:不須要那麼多的查詢(一個文檔一個文檔找索引,找到就匹配,須要所有查詢,效率很低),並且能夠在索引上定位,出如今哪一個文檔哪一個地方,支持高亮
Lucene是一個基於Java的全文檢索庫,能夠當作一個持久層框架,與Lucene索引交互mysql
左邊保存的是一系列字符串,稱爲詞典。web
每一個字符串都指向包含此字符串的文檔(Document)鏈表(每一個節點還包含文檔中出現該索引的頻率),此文檔鏈表稱爲倒排表(Posting List)。spring
若是咱們須要查詢包含兩個索引的文檔,只須要將兩個文檔共有的文檔標號鏈接成鏈表
詞元
分詞器通常使用訓練的模型,Word
、IK
等
英文:複數->單數,大寫->小寫sql
keyword:Java
1. 索引過程:數據庫
1) 有一系列被索引文件apache
2) 被索引文件通過語法分析和語言處理造成一系列詞(Term)。segmentfault
3) 通過索引建立造成詞典和反向索引表。緩存
4) 經過索引存儲將索引寫入硬盤。app
2. 搜索過程:
a) 用戶輸入查詢語句。
b) 對查詢語句通過語法分析和語言分析獲得一系列詞(Term)。
c) 經過語法分析獲得一個查詢樹。
d) 經過索引存儲將索引讀入到內存。
e) 利用查詢樹搜索索引,從而獲得每一個詞(Term)的文檔鏈表,對文檔鏈表進行交,差,並獲得結果文檔。
f) 將搜索到的結果文檔對查詢的相關性進行排序。
g) 返回查詢結果給用戶。
Solr是Lucene的封裝,提供分佈式索引,負載均衡查詢,配置式使用,基本只支持Java
solr create -c 「name」
http://localhost:8983/solr
在其中配置core的field字段、分詞器等
name:數據庫字段,type:類型,indexed:是否索引,stored:是否緩存,required:是否必須,multiValued:是否多值
<!-- ik分詞器 --> <fieldType name="text_ik" class="solr.TextField"> <analyzer type="index"> <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> <analyzer type="query"> <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true" conf="ik.conf"/> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> </fieldType> <!-- 數據庫字段 --> <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" /> <field name="shoes_name" type="text_ik" indexed="true" stored="true" multiValued="false"/> <field name="price" type="string" indexed="false" stored="true" multiValued="false"/> <field name="details" type="text_ik" indexed="true" stored="true" multiValued="false"/> <field name="url" type="string" indexed="false" stored="true" multiValued="false"/> <field name="pic_url" type="string" indexed="false" stored="true" multiValued="false"/>
當你須要使用web客戶端dataimport時,須要添加:
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler"> <lst name="defaults"> <str name="config">data-config.xml</str> </lst> </requestHandler>
<dataConfig> <dataSource type="JdbcDataSource" driver="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/priceCompare_goods" user="dzou" password="1234"/> <document> <entity name="adidas_goods" transformer="DateFormatTransformer" query="SELECT id,shoes_name,details,pic_url,price,url,store_name,comment,shoes_kind FROM adidas_goods"> <field column="id" name="id"/> <field column="shoes_name" name="shoes_name"/> <field column="price" name="price"/> <field column="details" name="details"/> <field column="url" name="url"/> <field column="pic_url" name="pic_url"/> <field column="shoes_kind" name="shoes_kind"/> <field column="store_name" name="store_name"/> <field column="score" name="score"> </entity> </document> </dataConfig>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-solr</artifactId> </dependency>
@RequestMapping("/add") public String add() throws IOException, SolrServerException { SolrInputDocument doc = new SolrInputDocument(); doc.setField(); doc.setField(); doc.setField(); solrClient.add("",doc); solrClient.commit(""); return ""; }
@RequestMapping("/delete") public String delete(String id) throws IOException, SolrServerException { solrClient.deleteById(id); solrClient.commit(""); return ""; } /** * 刪除全部的索引 * @return */ @RequestMapping("deleteAll") public String deleteAll(){ try { solrClient.deleteByQuery("","*:*"); solrClient.commit(""); return "success"; } catch (Exception e) { e.printStackTrace(); } return "error"; }
Map<String, String> map = new HashMap<>(); map.put("set", o.getScore()); SolrInputDocument doc = new SolrInputDocument(); doc.addField("id", o.getId()); doc.addField("score", map); solrClient.add("am_goods", doc); solrClient.commit("am_goods");
/** * 根據id查詢索引 * @return * @throws Exception */ @RequestMapping("getById") public String getById() throws Exception { SolrDocument document = solrClient.getById("collection1", "536563"); System.out.println(document); return document.toString(); } /** * 綜合查詢: 在綜合查詢中, 有按條件查詢, 條件過濾, 排序, 分頁, 高亮顯示, 獲取部分域信息 * @return */ @RequestMapping("search/{keyword}") public String search(@PathVariable("keyword")String keyword){ try { SolrQuery params = new SolrQuery(); //查詢條件, 這裏的 q 對應 下面圖片標紅的地方 params.set("q", "shoes_name:"+keyword); //過濾條件 //params.set("fq", "product_price:[100 TO 100000]"); //排序 params.addSort("price", SolrQuery.ORDER.asc); //分頁 params.setStart(0); params.setRows(20); //默認域 params.set("df", "shoes_name"); //只查詢指定域 //params.set("fl", "id,shoes_name,shoes_kind,shop_name"); //高亮 //打開開關 params.setHighlight(true); //指定高亮域 params.addHighlightField("shoes_name"); //設置前綴 params.setHighlightSimplePre("<span style='color:red'>"); //設置後綴 params.setHighlightSimplePost("</span>"); QueryResponse queryResponse = solrClient.query(params); /*SolrDocumentList results = queryResponse.getResults(); results.forEach(System.out::println);*/ List<HupuGoods> s = queryResponse.getBeans(HupuGoods.class); return s.toString(); } catch (Exception e) { e.printStackTrace(); } return null; }