Springboot+AngularJS+Spring-data-Solr:搜尋內容匹配高亮顯示
阿新 • • 發佈:2018-11-28
Java後臺部分:
package com.phubing.search.service.impl; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.solr.core.SolrTemplate; import org.springframework.data.solr.core.query.Criteria; import org.springframework.data.solr.core.query.HighlightOptions; import org.springframework.data.solr.core.query.HighlightQuery; import org.springframework.data.solr.core.query.Query; import org.springframework.data.solr.core.query.SimpleHighlightQuery; import org.springframework.data.solr.core.query.SimpleQuery; import org.springframework.data.solr.core.query.result.HighlightEntry; import org.springframework.data.solr.core.query.result.HighlightEntry.Highlight; import org.springframework.data.solr.core.query.result.HighlightPage; import org.springframework.data.solr.core.query.result.ScoredPage; import com.alibaba.dubbo.config.annotation.Service; import com.phubing.pojo.TbItem; import com.phubing.search.service.ItemSearchService; /** * 如果搜尋時間過長,會造成搜尋超時 * dubbo搜尋時間預設為1秒鐘 * 併發高或者伺服器效能不夠 * 可以加上@Service(timeout=3000)註解,設定dubbo超時時間 * 如果服務方和消費方同時設定了超時時間,dubbo會以消費方的設定為準 * * @author phubing * */ @Service(timeout=3000) public class ItemSearchServiceImpl implements ItemSearchService{ @Autowired private SolrTemplate solrTemplate; @Override public Map<String, Object> search(Map searchMap) { Map<String, Object> map = new HashMap<String, Object>(); /*Query query = new SimpleQuery("*:*"); //is表示匹配 *//** * { * "keywords":"關鍵字" * } *//* Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords")); query.addCriteria(criteria ); ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class); //將當前返回結果返回給rows *//** * 返回的格式為 * {rows:[]} * *//* map.put("rows", page.getContent());*/ HighlightQuery query = new SimpleHighlightQuery(); HighlightOptions highlightOptions = new HighlightOptions().addField("item_title"); //字首 highlightOptions.setSimplePrefix("<strong style=\'color:red;\'>"); //字尾 highlightOptions.setSimplePostfix("</strong>"); //為查詢物件設定高亮選項 /** * <strong style="color:red;">搜尋關鍵字/詞</strong> */ query.setHighlightOptions(highlightOptions); //關鍵字查詢 Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords")); query.addCriteria(criteria ); //返回一個高亮頁物件 HighlightPage<TbItem> page = solrTemplate.queryForHighlightPage(query, TbItem.class); /** * 1、此時可以獲取到一個不經過高亮處理的內容 page.getContent() * 2、需要從高亮入口集合獲取 * 3、entryList集合的每個物件,就是每條記錄的內容 * 4、HighlightEntry<TbItem>是高亮入口物件,存在一個獲取所有高亮的方法 * 5、高亮列表中為何還有一個高亮列表? * 5.1 HighlightOptions().addField設定高亮列,並且可以建立多個高亮列 * 5.2 建立了多個高亮列就會返回多個高亮列 * 6、為何Highlight highlightEntry也是一個高亮列,而不是直接獲取一個高亮值? * 6.1 每一個域有可能儲存多值,在schema.xml中配置了N個單獨的field,所以每一個高亮列都有其單獨的域 * 7、如何讓頁面產生高亮結果? * 7.1 從高亮列表中獲取高亮列,highlightsList.get(0).getSnipplets().get(0) * 7.2 將高亮頁賦予結果集page.getContent():item.setTitle(highlightsList.get(0).getSnipplets().get(0)); * */ //需要從返回高亮物件中獲取高亮結果再返回,即在高亮入口集合中遍歷 List<HighlightEntry<TbItem>> entryList = page.getHighlighted(); for (HighlightEntry<TbItem> entry : entryList) { //得到一個高亮列表 List<Highlight> highlightsList = entry.getHighlights(); //是否還需要遍歷取決於高亮列的個數 /*for (Highlight highlightEntry : highlightsList) { List<String> snippletsList = highlightEntry.getSnipplets(); }*/ if(highlightsList.size() > 0 && highlightsList.get(0).getSnipplets().size() > 0) { //與page.getContent()是同一個 TbItem item = entry.getEntity(); //確定只有一列的情況下 item.setTitle(highlightsList.get(0).getSnipplets().get(0)); } } map.put("rows", page.getContent()); return map; } }
AngularJS中controller層:
/*
Angularjs為了防止(html、js)攻擊,會將後端返回的html程式碼原樣輸出,此時需要採用$sce,即Angularjs信任策略,使用後就會解析後再輸出
trustHtml、trustJs
將過濾服務封裝成通用過濾器
*/
//封裝通用過濾器
app.filter('trustHtml',['$sce', function($sce){
//傳入的引數就是需要過濾的內容
return function(data){
return $sce.trustAsHtml(data);
}
}]);
頁面呼叫:
<div class="attr" ng-bind-html="item.title | trustHtml"></div>