繼上次匆匆搭建起結合solr和nutch的所謂站內搜索引擎之后,雖當時心中興奮不已,可是看了看百度,再只能看看我的控制台的打印出每個索引項的幾行文字,哦,好像差距還是有點大……
簡陋的信息顯示環境最起碼給了我一個信號,這條路沒有走錯,好吧,讓我們來繼續探索搜索引擎的奧秘吧。
上期回顧:上次主要是介紹了solrj,通過solrj的api與solr服務器進行通信,獲取服務器上的索引數據以及在編寫程序中遇到的一些問題和解決方法。本期主要是建立與solr服務器的通信,提供搜索界面輸入關鍵字或搜索規則,根據關鍵字或規則到索引數據中尋找匹配項並返回結果到界面上。
1.本篇的前提是你已經配置好nutch以及solr,並通過網頁爬取將索引數據存放到了solr服務器中(solr可以可以部署到tomcat的下也可以不部署,另外我的所有搭建都是在Ubuntu環境下),我配置了中文分詞器,以上工作可以在網上搜,資料很多,過程中也有很多錯誤需要解決,如果有時間我會對這塊做個總結,solr服務器的界面如下:


接下來就是要做一個搜索界面,基於是一個純所搜引擎,所以提供一個招牌、一個輸入框以及一個確認按鈕即可,關於招牌定什么,問過朋友,有吸引眼球的千度、谷哥哥,一看就是要和度娘們叫板,算了咱不干以卵擊石的事,還是有點自知之明的好,最終還是叫“jiesearch”吧——小眾,不矯情。這塊不涉及什么代碼量,所以就多扯了幾句,界面如下:

2.針對上次主題代碼進行完善,因為上次返回的是一個SolrDocumentList 對象,不能直接轉換為到jsp頁面顯示的list集合,所以借鑒網上前輩們的指點對代碼進行了改寫。
//首先定義HttpSolrServer對象,用於程序連接solr
1 public class SolrServer { 2 private static SolrServer solrServer = null; 3 private static HttpSolrServer server=null; 4 private static String url="http://solrIP:8080/solr"; 5 6 public static synchronized SolrServer getInstance() { 7 if (solrServer==null){ 8 solrServer=new SolrServer(); 9 } 10 return solrServer; 11 } 12 public static HttpSolrServer getServer(){ 13 try { 14 if(server==null){ 15 server = new HttpSolrServer(url); 16 server.setSoTimeout(1000); // socket read timeout 17 server.setConnectionTimeout(1000); 18 server.setDefaultMaxConnectionsPerHost(100); 19 server.setMaxTotalConnections(100); 20 server.setFollowRedirects(false); // defaults to false 21 //allowCompression defaults to false. 22 //Server side must support gzip or deflate for this to have any effect. 23 server.setAllowCompression(true); 24 server.setMaxRetries(1); // defaults to 0. > 1 not recommended. 25 } 26 } catch (Exception e) { 27 // TODO Auto-generated catch block 28 e.printStackTrace(); 29 } 30 return server; 31 } 32 }
//然后定義一個實體類BlogsDo用於接收和配置索引的各個字段
1 @Entity 2 @Table(name="blogs") 3 public class BlogsDO implements Serializable{ 4 private static final long serialVersionUID = -4721368786493126226L; 5 @Field("Id") 6 private String id; 7 @Field("content") 8 private String content; 9 @Field("title") 10 private String title; 11 @Field("url") 12 private String url; 13 @Field("_version_") 14 private String _version_; 15 public String getId() { 16 return id; 17 } 18 public void setId(String id) { 19 this.id = id; 20 } 21 public String getContent() { 22 return content; 23 } 24 public void setContent(String content) { 25 this.content = content; 26 } 27 public String getTitle() { 28 return title; 29 } 30 public void setTitle(String title) { 31 this.title = title; 32 } 33 public String getUrl() { 34 return url; 35 } 36 public void setUrl(String url) { 37 this.url = url; 38 } 39 public String get_version_() { 40 return _version_; 41 } 42 public void set_version_(String version) { 43 _version_ = version; 44 } 45 public static long getSerialversionuid() { 46 return serialVersionUID; 47 } 48 }
備注:這些字段相應的都應該在schema.xml中存在<fields></fields>之間,如下所示,另外個人理解,對於實體類上的注解 @Field("")應該也是一種映射,就是將實體類的字段與配置文件中的選項相對應。
<field name="id" type="string" stored="true" indexed="true"/>
<field name="_version_" type="long" indexed="true" stored="true"/>
<!-- fields for index-basic plugin -->
<field name="url" type="url" stored="true" indexed="true"required="true"/>
<field name="content" type="text" stored="true" indexed="true"/>
<field name="title" type="text" stored="true" indexed="true"/>
<field name="_version_" type="long" indexed="true" stored="true"/>
<!-- fields for index-basic plugin -->
<field name="url" type="url" stored="true" indexed="true"required="true"/>
<field name="content" type="text" stored="true" indexed="true"/>
<field name="title" type="text" stored="true" indexed="true"/>
//添加查詢規則以及是否高亮的設置以及結果的返回與接收
1 String searchWord=request.getParameter("searchText"); 2 List<BlogsDO> blogList=new ArrayList<BlogsDO>(); 3 BlogsDO blogsDO=null; 4 HttpSolrServer solrServer= SolrServer.getInstance().getServer(); 5 SolrQuery sQuery = new SolrQuery(); 6 String para=""; 7 Page page=null; 8 para="content:"+searchWord+""; 9 10 logger.info("para:"+para); 11 sQuery.setQuery(para); 12 sQuery.setStart(0); 13 sQuery.setRows(10); 14 //設置高亮 15 sQuery.setHighlight(true); // 開啟高亮組件 16 sQuery.addHighlightField("content");// 高亮字段 17 sQuery.addHighlightField("title");// 高亮字段 18 sQuery.setHighlightSimplePre("<font color='red'>");//標記,高亮關鍵字前綴 19 sQuery.setHighlightSimplePost("</font>");//后綴 20 sQuery.setHighlightSnippets(2);//結果分片數,默認為1 21 sQuery.setHighlightFragsize(1000);//每個分片的最大長度,默認為100 22 23 //分片信息 24 sQuery.setFacet(true) 25 .setFacetMinCount(1) 26 .setFacetLimit(5)//段 27 .addFacetField("content");//分片字段 28 29 long startSearch=System.currentTimeMillis(); 30 Integer counts=0; 31 try { 32 QueryResponse response = solrServer.query(sQuery); 33 SolrDocumentList list = response.getResults(); 34 counts=(int) list.getNumFound();//搜索數量 35 logger.info("counts:"+counts); 36 //獲取所有高亮的字段 37 Map<String,Map<String,List<String>>> highlightMap=response.getHighlighting(); 38 String blogId=""; 39 for (SolrDocument solrDocument : list) { 40 blogsDO=new BlogsDO(); 41 blogId=(String) solrDocument.getFieldValue("id").toString(); 42 blogsDO.setId(blogId); 43 blogsDO.set_version_(solrDocument.getFieldValue("_version_").toString()); 44 blogsDO.setUrl(solrDocument.getFieldValue("url").toString()); 45 46 List<String> titleList=highlightMap.get(blogId).get("title"); 47 List<String> contentList=highlightMap.get(blogId).get("content"); 48 if(titleList!=null && titleList.size()>0){ 49 blogsDO.setTitle(titleList.get(0)); 50 }else{ 51 //獲取並設置高亮的字段title 52 blogsDO.setTitle(solrDocument.getFieldValue("title").toString()); 53 } 54 if(contentList!=null && contentList.size()>0){ 55 blogsDO.setContent(contentList.get(0)); 56 }else{ 57 //獲取並設置高亮的字段content 58 blogsDO.setContent(solrDocument.getFieldValue("content").toString()); 59 } 60 blogList.add(blogsDO); 61 } 62 } catch (SolrServerException e) { 63 e.printStackTrace(); 64 } 65 long endSearch=System.currentTimeMillis(); 66 model.addObject("time", (double)(endSearch-startSearch)/1000); 67 model.addObject("counts", counts); 68 model.addObject("blogList", blogList);
3.下面要做的就是在前台jsp頁面中接收list集合和傳過去的counts(搜索結果個數),time(搜索耗時)並相應的調整界面布局即可,效果如下:

至此一個搜索引擎做的算是有點模樣了,下一步如果還有時間可以對本地文檔圖片等建立索引並實現搜索功能。
另外最近我在看大數據可視化方面的東西,如果有興趣有見解的可以交流下
郵箱:zjhxp_1990@163.com
文中如有不足和錯誤還請指正!
參考博文:http://blog.csdn.net/chunming8302/article/details/7321501
友情贊助
如果你覺得博主的文章對你那么一點小幫助,恰巧你又有想打賞博主的小沖動,那么事不宜遲,趕緊掃一掃,小額地贊助下,攢個奶粉錢,也是讓博主有動力繼續努力,寫出更好的文章^^。
1. 支付寶 2. 微信