大致的流程:
页面捕获到文字 --> 传到servlet(Controller)层,servlet层调用后台 --> 后台根据servlet层传来的参数进行动态从solr中获取数据 --> solr 数据返回到servlet层,解析 --> 展现到页面上。
在solr里面新建一个core,在MySQL数据库里面新建一个表,从这个表导入数据到solr的core中,具体步骤可以上网查或者看我前面的教程。
SQL语句:
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for lifeixroles -- ---------------------------- DROP TABLE IF EXISTS `lifeixroles`; CREATE TABLE `lifeixroles` ( `id` int(11) NOT NULL AUTO_INCREMENT, `accountId` int(11) DEFAULT NULL, `level` int(11) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, `accountName` varchar(255) DEFAULT NULL, `namePinyin` varchar(255) DEFAULT NULL, `l99NO` int(11) DEFAULT NULL, `photoPath` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of lifeixroles -- ---------------------------- INSERT INTO `lifeixroles` VALUES ('1', '4', '38', '崭露头脚', 'peter', 'peter', '150104', '02/MjAwOTAzMjgyMTM1NTdfMjIwLjI0OS43OS4zNV8zMzM2MDI=.jpg'); INSERT INTO `lifeixroles` VALUES ('2', '8', '1', '小虾米', '立方咖啡', 'lifangkafei', '150108', '20/MjAwOTAyMTYwMzQxMjBfMjIwLjI0OS43OS4zNV82MDYwNTc=..JPG'); INSERT INTO `lifeixroles` VALUES ('3', '11', '46', '名动江湖', 'nick', 'nick', '150121', '10/MjAxNDA2MTMxMTQ2MDVfMTkyLjE2OC4xOTkuNTdfNTA0NDcy.jpg'); INSERT INTO `lifeixroles` VALUES ('4', '10', '1', '小虾米', 'oz', 'oz', '150130', '21/MjAxMjEyMjExNTA5MzlfMTgzLjM3LjM0LjI5XzIzMjA1Nw==.png'); INSERT INTO `lifeixroles` VALUES ('5', '49', '46', '李四', '立方方圆', 'li', '150163', '10/MjAwOTAyMDcxMjQwMzBfMjIwLjI0OS43OS4zNV83MjQ3ODI=..jpg');
schema.xml的部分配置参考:
分词器:
指定数据库配置文件:
由于新建core是拷贝solr-4.10.2\example\multicore这里面的core,所以配置文件非常简单。在自己的core里面看看分词器是否有用,结果显示是有用的:
可是到搜索里面搜索指定字段的部分词语时,搜索不出,只能搜索出全名的:
查找故障很久都找不出为什么,包括把multiValued改为true,虽然不知道具体原因,但是改了这个,但是没有用,显示出的结果带方括号而已。
后来把这些数据导入collection1就正常了,可能是一些关键的东西没有配置,因为原来core里面的配置是最简单的基础配置,这有待于后面的仔细研究学习。搜索出关键词的数据:
这样就好办了,开始编码!
后台还是servlet和json的jar包生成json数据返回到前台页面,具体步骤可以看我前面的总结教程。
对象转换成json语句的工具类:src\com\lifeix\util\FastJsonUtil.java
package com.lifeix.util; import com.alibaba.fastjson.JSON; /** * Created by lhx on 14-12-10 下午4:15 * * @project jspProject * @package com.lifeix.util * @blog http://blog.csdn.net/u011439289 * @email [email protected] * @Description */ public class FastJsonUtil { /** * Object实体转换为json * @param object * @return */ public static String object2json(Object object){ JSON json = (JSON) JSON.toJSON(object); return json.toJSONString(); } }
后台从solr服务器上获取数据的处理类:\src\com\lifeix\util\SolrGetFtTopic2.java
package com.lifeix.util; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.params.ModifiableSolrParams; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by lhx on 14-12-9 上午10:30 * * @project jspProject * @package com.lifeix.util * @blog http://blog.csdn.net/u011439289 * @email [email protected] * @Description */ public class SolrGetFtTopic2 { private static final String SOLR_URL = "http://localhost:8080/solr/collection1"; public String queryAll(String htmlWord){ ModifiableSolrParams params = new ModifiableSolrParams(); params.set("q","accountName:"+htmlWord); params.set("start",0); params.set("rows",10); params.set("sort","score desc"); params.set("f1","*,score"); SolrServer server = new HttpSolrServer(SOLR_URL); List<Map<String,Object>> listWord = new ArrayList<Map<String, Object>>(); Map<String,Object> map = null ; try { QueryResponse response = server.query(params); SolrDocumentList list = response.getResults(); for (int i = 0; i < list.size(); i++) { map = new HashMap<String, Object>(); SolrDocument document = list.get(i); map.put("label",document.getFieldValue("l99NO") ); map.put("value", document.getFieldValue("accountName")); listWord.add(map); } return FastJsonUtil.object2json(listWord) ; } catch (SolrServerException e) { e.printStackTrace(); } return null ; } }
Servlet层从前台页面获取输入值,再交给后台处理
\src\com\lifeix\servlet\JsonSolrServlet.java
package com.lifeix.servlet; import com.lifeix.util.SolrGetFtTopic2; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * Created by lhx on 14-12-10 下午5:29 * * @project jspProject * @package ${PACKAGE_NAME} * @blog http://blog.csdn.net/u011439289 * @email [email protected] * @Description */ public class JsonSolrServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取网页上文本框输入的内容 String htmlWord = request.getParameter("term").trim(); String jsonStr = "" ; SolrGetFtTopic2 solrGetFtTopic = new SolrGetFtTopic2(); if (!"".equals(htmlWord) && htmlWord != null){ //传入参数,根据参数来进行搜索 jsonStr = solrGetFtTopic.queryAll(htmlWord); } PrintWriter pw = null; try { response.setContentType("application/json; charset=utf-8"); response.setCharacterEncoding("UTF-8"); response.setHeader("Cache-Control", "no-cache"); pw = response.getWriter(); pw.print(jsonStr); pw.flush(); }catch (Exception e) { e.printStackTrace(); } finally { if (pw != null) pw.close(); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
现在是前台页面的jQuery UI Autocomplete代码,这些代码可以参考
jQuery UI Autocomplete官网的远端缓存处理例子:
http://jqueryui.com/autocomplete/#remote-with-cache
jQuery UI Autocomplete是jQuery UI的自动完成组件
我的代码如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Fancy Validate - jQuery UI Autocomplete</title> <link href="jquery-ui/css/ui-lightness/jquery-ui-1.8.17.custom.css" rel="stylesheet" /> <script src="js/jquery-1.7.1.min.js"></script> <script src="jquery-ui/js/jquery-ui-1.8.17.custom.min.js"></script> <script src="jquery-ui/js/jquery-ui-widget-combobox.js"></script> <style> body { font-size: 14px; } fieldset { width: 650px; margin: 0 auto; text-align: right; } fieldset div { margin: 15px auto; } .cbo .ui-button-text { line-height: 1.3; padding-top: 0; padding-bottom: 0; } .cbo .ui-autocomplete-input { width: 7.2em; } </style> <script> $(function() { var cache = {}; $("#username").autocomplete({ minLength: 2, source:function(request, response){ var term = request.term; if(term in cache){ response(cache[term]); return ; } $.getJSON('jsonsolr',request,function(data,status,xhr){ cache[term] = data ; response(data); }); } }); var cache1 = {}; $("#username1").autocomplete({ minLength: 2, source:function(request, response){ var term = request.term; if(term in cache1){ response(cache1[term]); return ; } $.getJSON('jsonsolr2',request,function(data,status,xhr){ cache1[term] = data ; response(data); }); } }); var cache2 = {}; $("#l99NO").autocomplete({ minLength: 6, source:function(request, response){ var term = request.term; if(term in cache2){ response(cache2[term]); return ; } $.getJSON('jsonsolrl99',request,function(data,status,xhr){ cache2[term] = data ; response(data); }); } }); // 自定义source函数 var hosts = ["gmail.com", "live.com", "hotmail.com", "yahoo.com", "cnblogs.com", "火星.com", "囧月.com"]; $("#email1").autocomplete({ autoFocus: true, source: function(request, response) { var term = request.term, //request.term为输入的字符串 ix = term.indexOf("@"), name = term, // 用户名 host = "", // 域名 result = []; // 结果 result.push(term); // result.push({ label: term, value: term }); // json格式 if (ix > -1) { name = term.slice(0, ix); host = term.slice(ix + 1); } if (name) { var findedHosts = (host ? $.grep(hosts, function(value) { return value.indexOf(host) > -1; }) : hosts), findedResults = $.map(findedHosts, function(value) { return name + "@" + value; //返回字符串格式 // return { label: name + " @ " + value, value: name + "@" + value }; // json格式 }); result = result.concat($.makeArray(findedResults)); } response(result); //呈现结果 } }); /* combobox autocomplete */ $("#combo1").combobox(); }); </script> </head> <body> <form action="?" id="fancyform"> <fieldset> <legend>jQuery UI Autocomplete</legend> <div> 根据用户名搜索(输词语,如:立方,提示龙号):<input id="username" type="text" /> </div> <div> 根据用户名搜索(输词语,如:立方,提示用户名):<input id="username1" type="text" /> </div> <div> 根据龙号来搜索(输全部,如:150108):<input id="l99NO" type="text" /> </div> <div> Email(随便输):<input id="email1" type="text" /> </div> <div class="cbo"> Combobox(选择):<select id="combo1"> <option value="">请选择</option> <option value="1">地球</option> <option value="2">月球</option> <option value="3">火星</option> </select> </div> </fieldset> </form> </body> </html>
最后的实现效果如下:
——————————————————————————
——————————————————————————————————————————
后记:
因为前面改过multiValued的值,改为true了,所以搜索返回的值是带方括号的,导致生成的json语句不是正规的json,所以前台页面解析不了,通过断点调试可以发现这个问题:
另外这个例子还有一个缺点,就是中文输入的话,输入词语不能马上触发事件,要接着敲键盘或者敲一个空格键,jQuery才会把文本中的文字送到后台处理,而英文和数字没有这个问题,这个还要处理!
资料下载:http://pan.baidu.com/s/1jG1gAHK