189 8069 5689

lucene+jquery+struts2json插件实现搜索框自动补全

看了一堆自动补齐的例子,大多都是只有前台没有后台,有后台也是在后台写死的数据,所以不具有真实的实用性,拿来学习还是可以的,但也是仅仅限于jquery的学习。

创新互联-专业网站定制、快速模板网站建设、高性价比潍城网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式潍城网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖潍城地区。费用合理售后完善,10余年实体公司更值得信赖。

接下来我要写一个从后台数据库生成lucene索引文件,在struts2Action中查根据key值查询索引文件,获取到部分符合关键字(key值)的数据,通过json格式返回到前台页面,在使用jquery完成自动补齐的完整例子。

首先第一步从数据库中获取索引文件。

  1. package com.net263.boss.charge.action;  
  2.  
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import org.apache.log4j.Logger;  
  6. import org.apache.lucene.analysis.standard.StandardAnalyzer;  
  7. import org.apache.lucene.document.Document;  
  8. import org.apache.lucene.document.Field;  
  9.  
  10. import org.apache.lucene.index.IndexWriter;  
  11.  
  12. import org.quartz.JobExecutionContext;  
  13. import org.quartz.JobExecutionException;  
  14. import org.springframework.scheduling.quartz.QuartzJobBean;  
  15.  
  16. import com.net263.boss.business.service.ICustomerService;  
  17. public class CreateSearchIndex extends QuartzJobBean {  
  18.  
  19.     /* 
  20.      * (non-Javadoc) 
  21.      *  
  22.      * @see 
  23.      * org.springframework.scheduling.quartz.QuartzJobBean#executeInternal(org 
  24.      * .quartz.JobExecutionContext) 
  25.      */ 
  26.     private ICustomerService customerService;  
  27.  
  28.  
  29.     /** 
  30.      * @return the customerService 
  31.      */ 
  32.     public ICustomerService getCustomerService() {  
  33.         return customerService;  
  34.     }  
  35.     /** 
  36.      * @param customerService the customerService to set 
  37.      */ 
  38.     public void setCustomerService(ICustomerService customerService) {  
  39.         this.customerService = customerService;  
  40.     }  
  41.     private static Logger logger = Logger.getLogger(CreateSearchIndex.class);  
  42.     public void executeInternal(JobExecutionContext context)  
  43.             throws JobExecutionException {  
  44.         String path = this.getClass().getClassLoader().getResource("").getPath().replace(" ","\" \"")+"index";  
  45.         logger.info("begin...");  
  46.         //path=path.substring(1).trim(); 
  47.         logger.info("index path is :"+path);  
  48.         List list = new ArrayList();  
  49.         IndexWriter writer;  
  50.         try {  
  51.             list = customerService.queryCustomerName();  
  52.             logger.info("get index successfully.");  
  53.         } catch (Exception e) {  
  54.             e.printStackTrace();  
  55.         }  
  56.         try {  
  57.             writer = new IndexWriter(path,new StandardAnalyzer(),true);  
  58.             for(String tempC : list)  
  59.             {  
  60.                 if(tempC==null || "".equals(tempC))  
  61.                     {  
  62.                     continue;  
  63.                     }  
  64.                 else 
  65.                 {  
  66.                     Document docA = new Document();  
  67.                     Field fieldA = new Field("content",tempC,Field.Store.YES,Field.Index.TOKENIZED);  
  68.                     docA.add(fieldA);  
  69.                     writer.addDocument(docA);  
  70.                 }  
  71.                   
  72.             }  
  73.             //如果对海量数据进行创建索引的时候,需要对索引进行优化,以便提高速度 
  74.             writer.optimize();  
  75.             //跟数据库类似,打开一个连接,使用完后,要关闭它 
  76.             writer.close();  
  77.             logger.info("end...");  
  78.         } catch (Exception e) {  
  79.             e.printStackTrace();  
  80.             logger.info("error...");  
  81.         }   
  82.     }  
  83.  
  84. }  

以上代码是通过Quartz来进行启动的,每分钟进行一次索引文件的同步。

配置文件如下:

 

  1.      
  2.         
  3.       
  4.        
  5.      
  6.        
  7.      
  8.          
  9.      
  10.  
  11.       
  12.       
  13.        
  14.            
  15.    

好了,创建索引文件就基本完成了啊。

下面,我们来通过Action获取到所需的自动补全信息。

 

  1. import java.util.ArrayList;  
  2. import java.util.Date;  
  3. import java.util.List;  
  4.  
  5. import net.sf.json.JSONArray;  
  6.  
  7. import org.apache.log4j.Logger;  
  8. import org.apache.lucene.analysis.standard.StandardAnalyzer;  
  9. import org.apache.lucene.queryParser.QueryParser;  
  10. import org.apache.lucene.search.Hits;  
  11. import org.apache.lucene.search.IndexSearcher;  
  12. import org.apache.lucene.search.Query;  
  13. import org.apache.struts2.json.annotations.JSON;  
  14.  
  15. import com.net263.boss.util.JsonUtils;  
  16. import com.opensymphony.xwork2.ActionSupport;  
  17.  
  18. public class QueryCustomerNameAction extends ActionSupport {  
  19.     String path = this.getClass().getClassLoader().getResource("").getPath().replace(" ","\" \"")+"index";  
  20.     private String customerName;  
  21.     List list =new ArrayList();  
  22.     /** 
  23.      * @return the list 
  24.      */ 
  25.     public List getList() {  
  26.         return list;  
  27.     }  
  28.  
  29.     /** 
  30.      * @param list the list to set 
  31.      */ 
  32.     public void setList(List list) {  
  33.         this.list = list;  
  34.     }  
  35.  
  36.     private static final Logger LOGGER = Logger.getLogger(QueryCustomerNameAction.class);  
  37.  
  38.     public void setKey(String customerName) {  
  39.         this.customerName = customerName;  
  40.     }  
  41.  
  42.     public Query queryParser(String key){  
  43.         //content 为默认搜索的Field列名 
  44.         QueryParser queryParser = new QueryParser("content", new StandardAnalyzer());  
  45.         try {  
  46.             Query query =  queryParser.parse(key);  
  47.             return query;  
  48.         } catch (Exception e) {  
  49.             e.printStackTrace();  
  50.         }  
  51.         return null;  
  52.     }  
  53.       
  54.     public String searchName()  
  55.     {  
  56.         Date startTime,endTime;  
  57.         try {  
  58.               
  59.             IndexSearcher search = new IndexSearcher(path);  
  60.             startTime = new Date();  
  61.             //抽象的查询对象 
  62.             if(customerName!=null && !("".equals(customerName)))  
  63.             {  
  64.                 Query query = queryParser(customerName);  
  65.             //搜索结果集Hits 
  66.             Hits hits = search.search(query);  
  67.             for (int i = 0; i < hits.length(); i++) {  
  68.                 int beginIndex=hits.doc(i).toString().indexOf(":");  
  69.                 int endIndex=hits.doc(i).toString().indexOf(">");  
  70.                 list.add(hits.doc(i).toString().substring(beginIndex+1, endIndex));  
  71.                 System.out.println(hits.doc(i).toString().substring(beginIndex+1, endIndex));  
  72.                 if(i>8)  
  73.                 {  
  74.                     break;  
  75.                 }  
  76.             }  
  77.             }  
  78.             endTime = new Date();  
  79.             System.out.println("本次搜索用时:" + (endTime.getTime() - startTime.getTime()) + "毫秒");  
  80.             LOGGER.info("本次搜索用时:" + (endTime.getTime() - startTime.getTime()) + "毫秒");  
  81.             LOGGER.info("list:"+JsonUtils.listToJson(list));  
  82.         } catch (Exception e) {  
  83.             LOGGER.info("没有搜索到对应分词");  
  84.             //e.printStackTrace(); 
  85.         }  
  86.         return "success";  
  87.     }  
  88.  

这里面用到了struts2的json插件,这个插件很好用,它会把Action中所要返回的数据自动封装成json格式的,本例子中需要返回list,就会讲list中存放的数据json化。

需要特别提示的是:

 

  1.    
  2.        
  3.          
  4.          
  5.         list 
  6.            
  7.      
  8.   

需要继承json-default

这样,我们的后台基本就写完了。现在总结一下:后台主要完成的功能就是数据库到索引文件的同步和通过key查询索引文件返回json结果集的这么一个过程。

最后,我们来写前台jquery,这个大部分例子有用了,我就不再详细叙述了,只把代码贴出来。还要说明一点,大多数例子所捕获的键盘信息严重不足,我多加捕获了一些,包括输入汉字时输入法前的数字1-5,当然可以捕获更多。

 

  1. var highlightindex =-1;  
  2. $(document).ready(function() {  
  3.     var wordInput=$("#customerName");  
  4.     var wordInputOffset=wordInput.offset();  
  5.     var auto=$("#autoComplete").hide().css("border","3px white solid").css("background-color" ,"white")  
  6.     .css("position","absolute")  
  7.     .css("top",wordInputOffset.top+wordInput.height()+12+"px")  
  8.     .css("left",wordInputOffset.left+"px").width(wordInput.width()+6);  
  9.     wordInput.keyup(function(event){  
  10.         var myEvent =event || window.event;  
  11.         var keyCode = myEvent.keyCode;  
  12.         var wordText =$("#customerName").val();  
  13.         var actionurl="search.action";  
  14.         if(keyCode>=65 && keyCode<=90 ||keyCode==8 || keyCode==46 || keyCode==32 || keyCode==49 || keyCode==50 || keyCode==51 || keyCode==52 || keyCode==53)  
  15.         {  
  16.         if(wordText != ""){  
  17.                 $.ajax({    
  18.                     url : actionurl,    
  19.                     data : {key : wordText},    
  20.                     type : 'POST',    
  21.                     dataType : 'json',    
  22.                     success : function(data) {  
  23.                         $(auto).empty();  
  24.                                 $.each(data,function(index,term){  
  25.                                     var newDwNode = $("
    ").attr("id",index);  
  26.                                     newDwNode.html(term).appendTo(auto);  
  27.                                     //鼠标移入 
  28.                                     newDwNode.mouseover(function(){  
  29.                                         if (highlightindex != -1) {  
  30.                                             var autoNodes = $(auto).children("div");  
  31.                                             autoNodes.eq(highlightindex).css("background-color" ,"white").css("font-weight","normal");  
  32.                                         }  
  33.                                         highlightindex = $(this).attr("id");  
  34.                                         $(this).css("background-color","#CCCCFF").css("font-weight", "800");  
  35.                                     });  
  36.                                     //鼠标移出 
  37.                                     newDwNode.mouseout(function(){  
  38.                                         $(this).css("background-color" ,"white").css("font-weight","normal");  
  39.                                     });  
  40.                                     //鼠标单击 
  41.                                     newDwNode.click(function(){  
  42.                                         var dataText = $(this).text();  
  43.                                         wordInput.val(dataText);  
  44.                                         $(auto).hide();  
  45.                                     });  
  46.                                 });  
  47.                                 if(data.length>0)  
  48.                                 {  
  49.                                     $(auto).show();  
  50.                                 }  
  51.                                 else 
  52.                                 {  
  53.                                     $(auto).hide();  
  54.                                     parseInt(highlightindex) =-1;  
  55.                                 }  
  56.                     }    
  57.                 });   
  58.             }  
  59.         else 
  60.         {  
  61.             $(auto).hide();  
  62.             parseInt(highlightindex) =-1;  
  63.         }  
  64.         }  
  65.         else if(keyCode==38 || keyCode==40)  
  66.         {  
  67.             if(keyCode==38)//向上 
  68.             {  
  69.                 var autoNodes = $(auto).children("div");  
  70.                 if (highlightindex!= -1) {  
  71.                             autoNodes.eq(highlightindex).css("background-color" ,"white").css("font-weight","normal");  
  72.                             highlightindex=highlightindex-1;  
  73.                         } else {  
  74.                             parseInt(highlightindex)=autoNodes.length-1;  
  75.                         }  
  76.                 if (highlightindex == -1) {  
  77.                     highlightindex=autoNodes.length-1;  
  78.                 }  
  79.                 var dataText = autoNodes.eq(highlightindex).css("background-color","#CCCCFF").css("font-weight", "800").text();  
  80.                 wordInput.val(dataText);  
  81.             }  
  82.             if(keyCode==40)//向下 
  83.             {  
  84.                 var autoNodes = $(auto).children("div");  
  85.                 if (parseInt(highlightindex) != -1) {  
  86.                             autoNodes.eq(highlightindex).css("background-color" ,"white").css("font-weight","normal");  
  87.                         }   
  88.                 highlightindex=parseInt(highlightindex)+1;  
  89.                 if (highlightindex == autoNodes.length) {  
  90.                     highlightindex=0;  
  91.                 }  
  92.                 var dataText = autoNodes.eq(highlightindex).css("background-color","#CCCCFF").css("font-weight", "800").text();  
  93.                 wordInput.val(dataText);  
  94.             }  
  95.               
  96.         }else if(keyCode==13)//回车 
  97.         {  
  98.             $(auto).hide();   
  99.             highlightindex =-1;  
  100.         }  
  101.     })  
  102. }) 

最后显示效果如下:

 

lucene+jquery+struts2json插件实现搜索框自动补全

 


文章标题:lucene+jquery+struts2json插件实现搜索框自动补全
文章来源:http://cdxtjz.cn/article/jsjopd.html

其他资讯