首页 > 代码库 > solr进阶八:jQuery UI Autocomplete与solr搜索结合

solr进阶八:jQuery UI Autocomplete与solr搜索结合

大致的流程:

页面捕获到文字 --> 传到servletController)层,servlet层调用后台 --> 后台根据servlet层传来的参数进行动态从solr中获取数据 --> solr 数据返回到servlet层,解析 --> 展现到页面上。

 

solr里面新建一个core,在MySQL数据库里面新建一个表,从这个表导入数据到solrcore中,具体步骤可以上网查或者看我前面的教程。

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里面的配置是最简单的基础配置,这有待于后面的仔细研究学习。搜索出关键词的数据:

这样就好办了,开始编码!

后台还是servletjsonjar包生成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 888xin@sina.com
 * @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 888xin@sina.com
 * @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 888xin@sina.com
 * @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 AutocompletejQuery UI的自动完成组件

 

我的代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Fancy Validate - jQuery UI Autocomplete</title>
<link href=http://www.mamicode.com/"jquery-ui/css/ui-lightness/jquery-ui-1.8.17.custom.css" rel="stylesheet" />>


最后的实现效果如下:

——————————————————————————

——————————————————————————————————————————


后记:

因为前面改过multiValued的值,改为true了,所以搜索返回的值是带方括号的,导致生成的json语句不是正规的json,所以前台页面解析不了,通过断点调试可以发现这个问题:

另外这个例子还有一个缺点,就是中文输入的话,输入词语不能马上触发事件,要接着敲键盘或者敲一个空格键,jQuery才会把文本中的文字送到后台处理,而英文和数字没有这个问题,这个还要处理!



资料下载:http://pan.baidu.com/s/1jG1gAHK


solr进阶八:jQuery UI Autocomplete与solr搜索结合