Compass 更智能的搜索引擎(3)--高亮,排序,过滤以及各种搜索
要想使得一個搜索系統更加的完美,查詢精確度和頁面顯示算是其中比較重要的兩個方面。今天,我們就來談談怎么使得我們的搜索系統更加的完美。
- 關于分詞
- 下載地址
- 配置
- 關于高亮
- 關于排序
- 原理
- 冗余字段
- 使用方式
- 測試排序
- 關于過濾
- 原理
- 冗余字段
- 如何使用
- 測試過濾
- 關于查詢
- 總結
- 關于分詞
關于分詞
分詞的好壞直接關系到我們的查詢系統的精準度。所以一個更加適合的分詞方式很重要。對于中文而言,更是如此。
Compass配置分詞器簡直是不能再簡單了。我這里使用一個中科院研制的一個高效中文分詞器。JE-Analysis,
下載地址
配置
我們使用xml的方式對分詞器進行配置。
導入剛才下載的jar包之后,我們可以在項目的依賴中找到如圖所示信息。
右鍵紅色區域文件,點擊copy qualified name。然后配置成如下面貌即可。
<?xml version="1.0" encoding="UTF-8" ?> <compass-core-config xmlns="http://www.compass-project.org/schema/core-config"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.compass-project.org/schema/core-confighttp://www.compass-project.org/schema/compass-core-config-2.2.xsd"><compass name="default"><!-- 連接信息,好比數據庫的連接信息 --><connection><file path="./indexDir/" /></connection><!-- 映射信息,好比Hibernate的映射關系 --><mappings><class name="domain.Article" /></mappings><!-- 分詞器以及高亮器的配置 --><settings><!-- 分詞器的配置,可選擇中文的 --><setting name="compass.engine.amalyzer.default.type" value="jeasy.analysis.MMAnalyzer" /></settings></compass> </compass-core-config>好了,大功告成了。
關于高亮
對于高亮而言,我們其實并未真正的改變原始數據,而是將取出來的數據進行了一些包裝而已。這樣影響的僅僅是顯示在我們的頁面上數據。
高亮在Compass中更加方便,如下:
<?xml version="1.0" encoding="UTF-8" ?> <compass-core-config xmlns="http://www.compass-project.org/schema/core-config"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.compass-project.org/schema/core-confighttp://www.compass-project.org/schema/compass-core-config-2.2.xsd"><compass name="default"><!-- 連接信息,好比數據庫的連接信息 --><connection><file path="./indexDir/" /></connection><!-- 映射信息,好比Hibernate的映射關系 --><mappings><class name="domain.Article" /></mappings><!-- 分詞器以及高亮器的配置 --><settings><!-- 分詞器的配置,可選擇中文的 --><setting name="compass.engine.amalyzer.default.type" value="jeasy.analysis.MMAnalyzer" /><!-- 高亮器前綴 --><setting name="compass.engine.highlighter.default.formatter.simple.pre" value="<font color='red' >" /><!-- 高亮器后綴 --><setting name="compass.engine.highlighter.default.formatter.simple.post" value="</font>" /><!-- 高亮器摘要的長度 --><setting name="compass.engine.highlighter.default.fragmenter.simple.size" value="100" /></settings></compass> </compass-core-config>關于排序
類比國內某搜索引擎,排序其實并不公平。我們可以認為的控制排序,Compass亦是如此。
原理
不管是Compass還是數據庫,我們都會通過冗余字段來提高檢索速度。或者進行排序。所以我們會在bean對象中添加一個冗余字段來幫助我們對數據進行排序操作。
冗余字段
/*** @Date 2016年8月2日** @author Administrator*/ package domain;import org.compass.annotations.ExcludeFromAll; import org.compass.annotations.Index; import org.compass.annotations.Searchable; import org.compass.annotations.SearchableBoostProperty; import org.compass.annotations.SearchableId; import org.compass.annotations.SearchableProperty; import org.compass.annotations.Store;/*** * Compass的映射配置要求* * 在實體類上面有一個@Searchable注解<br>* * 在屬性上面,至少有一個有@SearchableId* * 其他的屬性只需要是@SearchableProperty即可* * * * @author 郭瑞彪*/ @Searchable public class Article {@SearchableIdprivate Integer id;// @SearchableProperty(store = Store.YES, index =// Index.ANALYZED,,excludeFromAll=ExcludeFromAll.YES)查詢的時候就會排除此項來進行查詢操作@SearchableProperty(store = Store.YES, index = Index.ANALYZED)private String title;@SearchableProperty(store = Store.YES, index = Index.ANALYZED)private String content;// 如果要想改變查詢結果的順序,這個bean里面就應該有一個記錄boostValue的值,這樣使用的時候在具體的結果集對象上進行修改即可@SearchableBoostPropertyprivate float boostValue = 1F;public float getBoostValue() {return boostValue;}public void setBoostValue(float boostValue) {this.boostValue = boostValue;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getTitle() {return title;}@Overridepublic String toString() {return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}}使用方式
我們在存儲數據的時候就可以指定某一個對象的權重了。即設置剛才的serBoostValue。這樣在我們獲取數據的時候,就會獲得排序的數據。
測試排序
@Testpublic void testBoostValueSearch() throws Exception {String queryString = "lucene";// 查詢,得到結果List<Article> articles = new ArrayList<Article>();// 建立索引Compass compassSessionFactory = CompassUtils.getCompassSessionFactory();CompassSession session = compassSessionFactory.openSession();CompassTransaction tx = session.beginTransaction();CompassHits hits = session.find(queryString);// 處理結果for (int i = 0; i < hits.length(); i++) {Article a = (Article) hits.data(i);if (i == 0)a.setBoostValue(2F);articles.add(a);}tx.commit();session.close();// 顯示結果System.out.println(articles.toString());for (Article a : articles) {System.out.println("-----------搜索結果如下-----------------");System.out.println(">>>id: " + a.getId());System.out.println(">>>title:" + a.getTitle());System.out.println(">>>content:" + a.getContent());}}關于過濾
原理
過濾的話,無非就是要哪一段數據,不要那一段數據。這自然是關乎到查詢方式的變化,同樣Compass就是基于這么個理念,賦予query對象新的filter。從而實現過濾操作。過濾的實現,同樣要依賴于一個冗余字段。(需要在這個字段上聲明@SearchableProperty注解)
冗余字段
/*** @Date 2016年8月2日** @author Administrator*/ package domain;import org.compass.annotations.ExcludeFromAll; import org.compass.annotations.Index; import org.compass.annotations.Searchable; import org.compass.annotations.SearchableBoostProperty; import org.compass.annotations.SearchableId; import org.compass.annotations.SearchableProperty; import org.compass.annotations.Store;/*** * Compass的映射配置要求* * 在實體類上面有一個@Searchable注解<br>* * 在屬性上面,至少有一個有@SearchableId* * 其他的屬性只需要是@SearchableProperty即可* * * * @author 郭瑞彪*/ @Searchable public class Article {@SearchableIdprivate Integer id;// @SearchableProperty(store = Store.YES, index =// Index.ANALYZED,,excludeFromAll=ExcludeFromAll.YES)查詢的時候就會排除此項來進行查詢操作@SearchableProperty(store = Store.YES, index = Index.ANALYZED)private String title;@SearchableProperty(store = Store.YES, index = Index.ANALYZED)private String content;// 為了過濾器所需@SearchableProperty(store = Store.YES, index = Index.ANALYZED)private int filmeta;public int getFilmeta() {return filmeta;}public void setFilmeta(int filmeta) {this.filmeta = filmeta;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getTitle() {return title;}@Overridepublic String toString() {return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}}如何使用
使用的時候需要將過濾信息附加到查詢對象query上,這樣才能生效。
CompassQuery query = null; CompassQueryFilter filter = null; filter = session.queryFilterBuilder().between("filmeta", 3, 7, true, true); query=session.queryBuilder().queryString(queryString).toQuery(); query.setFilter(filter);測試過濾
@Testpublic void testFilterSearch() throws Exception {String queryString = "lucene";// 查詢,得到結果List<Article> articles = new ArrayList<Article>();// 建立索引Compass compassSessionFactory = CompassUtils.getCompassSessionFactory();CompassSession session = compassSessionFactory.openSession();CompassTransaction tx = session.beginTransaction();CompassHits hits = null;CompassQuery query = null;CompassQueryFilter filter = null;// 構建查詢對象,我們可以使用這樣的queryBuilder方式創建出各式各樣的查詢方式,如布爾查詢,關鍵詞查詢,短語查詢,模糊查詢等等filter = session.queryFilterBuilder().between("filmeta", 3, 7, true, true);query = session.queryBuilder().queryString(queryString).toQuery();query.setFilter(filter);hits = query.hits();// 處理結果for (int i = 0; i < hits.length(); i++) {Article a = (Article) hits.data(i);if (i == 0)a.setBoostValue(2F);articles.add(a);}tx.commit();session.close();// 顯示結果System.out.println(articles.toString());for (Article a : articles) {System.out.println("-----------搜索結果如下-----------------");System.out.println(">>>id: " + a.getId());System.out.println(">>>title:" + a.getTitle());System.out.println(">>>content:" + a.getContent());}}關于查詢
在Compass中,查詢操作更是方便,我們只需要調用相關的API即可。如下圖
不難看出,各種查詢的底層就是基于過濾來實現的,所以我們可以一句過濾的操作來實現我們的各種查詢需求。
總結
經過了這兩天的搜索引擎框架的學習,基本上我們可以開發出適合自己項目需求的站內搜索或者全文搜索了。至此,本系列學習也到此結束。
如果我的這些文章恰好給對此迷茫的你一點靈光,我就非常的欣慰了。
:-)
總結
以上是生活随笔為你收集整理的Compass 更智能的搜索引擎(3)--高亮,排序,过滤以及各种搜索的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux 进程状态【转】
- 下一篇: 简易调用及实例化视图