`
mzlly999
  • 浏览: 52455 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
收藏列表
标题 标签 来源
PageModel
package com.liuyang.util;
import java.util.ArrayList;
import java.util.List;
/**
 * <code>PageModel</code> 的注释
 * @author 刘阳
 */

public class PageModel implements java.io.Serializable {
	
	/**
	 * 避免版本序列话问题,增加下面代码。
	 */
	private static final long serialVersionUID = 1L;


	/**
	 * 总记录数
	 */
	private int total;
	
	/**
	 * 当前页结果集
	 */
	private List datas = new ArrayList();
	
	/**
	 * 总页数
	 */
	private int pageCount;

	public int getPageCount() {
		return pageCount;
	}

	public void setPageCount(int pageCount) {
		this.pageCount = pageCount;
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public List getDatas() {
		return datas;
	}

	public void setDatas(List datas) {
		this.datas = datas;
	}
}
index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@page import="com.liuyang.lucene.ProductLucene"%> 
<%@page import="com.liuyang.util.PageModel"%> 
<%
ProductLucene productLucene = new ProductLucene();
int i = productLucene.getProductLucene();
PageModel pm = productLucene.searchProduct("apple",0,10);
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  	<title>测试页面</title>
  </head> 	
  <body>
    <%out.println("共有:"+i+"条记录生成索引。");%> <br>
    <%out.println("查询结果共有:"+pm.getDatas().size()+"条");%> <br>
    <%out.println("id分别是:");%> <br>
    <% for(int j=0;j<pm.getDatas().size();j++){
    	out.println(pm.getDatas().get(j)+"<br />");
       } 
       
    %>
    
  </body>
</html>
ProductLucene
package com.liuyang.lucene;

import java.io.BufferedReader;
import java.io.File;
import java.io.Reader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import org.apache.lucene.search.IndexSearcher;
import com.liuyang.util.PageModel;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
/**
 * 商品相关的Lucene
 * @author liuyang_js
 *
 */
public class ProductLucene {
	private static int TOP_NUM = 1000;//显示前1000条结果 
	static{
		try {
			Class.forName("com.mysql.jdbc.Driver").newInstance();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}
	
	
	/**
	 * 获得连接
	 */
	public static Connection getCon(){
		
		Connection con=null;
		String url = "jdbc:mysql://localhost:3306/test";
		String userName="root";
		String password="root";
		try {
			con = DriverManager.getConnection(url,userName,password); 
		} catch (Exception e) {
			e.printStackTrace();
		}  
		return con;
	}
	
	/**
	 * 生成商品索引
	 * @return 共生成了
	 */
	public int getProductLucene(){
		//声明索引文件
		File LuceneFile=new File("productlucene");
		//声明查询sql
		String sql = "select ProductId,ProductName,ProductIntr from product";
		//声明打开索引对象指针
		Directory directory = null;
		int i = 0;
		try {
			//为打开索引对象指针赋值
			directory = FSDirectory.open(LuceneFile);
			//声明分词器,此处使用的是标准分次器,即当前lucene版本的默认分词器。
			Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
			//创建IndexWriter对象,第一个参数是Directory,第二个是分词器,
			//第三个表示是否是创建,如果为false为在此基础上面修改,
			//第四表示表示分词的最大值,比如说new IndexWriter.MaxFieldLength(2),就表示两个字一分,一般用IndexWriter.MaxFieldLength.LIMITED 
			IndexWriter writer = new IndexWriter(directory, analyzer, true,
					IndexWriter.MaxFieldLength.LIMITED);
			//SetMergeFactor是控制segment合并频率的,其决定了一个索引块中包括多少个文档,
			//当硬盘上的索引块达到多少时,将它们合并成一个较大的索引块。
			//当MergeFactor值较大时,生成索引的速度较快。
			//MergeFactor的默认值是10,建议设置大一些,个人认为1000可以。
			writer.setMergeFactor(1000);
			
			//获取数据库连接
			Connection con = getCon();
			//声明PreparedStatement和ResultSet对象
			PreparedStatement ps=con.prepareStatement(sql);
			ResultSet rs =ps.executeQuery();
			while(rs.next()){
				i++;
				StringBuffer sb = new StringBuffer();
				//声明Document对象,在lucene中每个Document相当于数据库中的一条记录
				Document doc = new Document();
				//像Document对象增加Field,每个Field相当于数据库中的一个字段。
				//Field构造的四个参数,第一个代表名称,第二个代码内容
				//第三个是否存储,第四个是否分词
				doc.add(new Field("ProductId", rs.getLong(1)+"", Field.Store.YES, Field.Index.NOT_ANALYZED)) ;
				
				//因为第三个字段是text类型,所以需要使用流来读取
				Reader reader= rs.getCharacterStream(3);
				if(reader!=null){
					BufferedReader br= new BufferedReader(reader);
					String line = br.readLine();
					while(line != null){
	        			sb.append(line);
	        			line = br.readLine();   
	        		}
					//对Document对象增加"All"字段,字段由商品名和商品简介组合而成,不存储,分词
					doc.add(new Field("All", sb.append(" ").append(rs.getString(2)).toString(), Field.Store.NO, Field.Index.ANALYZED)) ;
					reader.close();
		        	br.close();
				}else{
					//如果商品简介取不到,则对Document对象增加"All"字段,内容为商品名,不存储,分词
	        		doc.add(new Field("All", rs.getString(2), Field.Store.NO, Field.Index.ANALYZED)) ;
	        	}
				//使用writer将Document写入。
				writer.addDocument(doc);
			}
			//关闭数据库连接使用的对象。
			ps.close();
	        rs.close(); 
	        con.close();  
	        
	        //对索引文件进行压缩、优化,此操作后所有索引文件将会变成一个。
	        writer.optimize();
	        //关闭writer
	        writer.close();
	        //关闭directory
	        directory.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return i;
	}
	
	/**
	 * 
	 * @param keyWord 关键字
	 * @param indexstart  开始位置
	 * @param length  一共查询多少条记录
	 * @return 分页对象
	 * @throws Exception 
	 */
	public PageModel searchProduct(String keyWord,int indexstart,int length) throws Exception{
		//声明pageModel对象,分页对象
		PageModel pm = new PageModel();
		//声明IndexSearcher
		IndexSearcher  searcher = null;
		//声明FSDirectory
		FSDirectory directory =null;
		//声明用于存放查询结果集的list
		List list = new ArrayList();
		//声明分词器,此处使用的是标准分次器,即当前lucene版本的默认分词器。此处需要和生成索引文件的分词器一致。
		Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
		//打开索引文件,此处文件应该为生成索引的文件地址。
		directory =FSDirectory.open(new File("productlucene"));
		//使用searcher打开索引文件
		searcher =new IndexSearcher(directory);
		//QueryParser是lucene中用来查询的类,构造有三个参数,第一个参数是分词器的版本,
		//第二个参数是查询的字段,第三个字段是分词器。
		QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "All", analyzer);
		//通过parser对象检索关键词,得到Query对象。
    	Query query = parser.parse(keyWord);
    	//通过searcher对象开始查询,调用search方法,有两个参数,
    	//第一个是query对象,第二个是查询上限是多少条
	    TopDocs hits = searcher.search(query, TOP_NUM);
	    
	    //通过开始记录的位置和要查询多少条记录,将末尾记录的位置算出来
	    int indexend = indexstart+length;
	    //如果结尾的记录位置大于查询出来的结果总数,那么使用结果总数,否则使用结尾的记录位置
		indexend = indexend>hits.totalHits?hits.totalHits:indexend;
		//根据开始位置和结尾位置循环。
		for (int i = indexstart; i < indexend; i++) {
			//使用下面代码可以返回第i条记录 在索引文件中的id
		    int id = hits.scoreDocs[i].doc;
		    //通过此ID 可以查询出Document对象
		    Document doc = searcher.doc(id);
		    //通过Document的get方法可以获得到他的属性值
		    long productId = Long.parseLong(doc.get("ProductId"));
		    //将查询出来的结果放到list中
			list.add(productId);
		}
		//声明totle对象 存放查询结果总数
		int totle =hits.totalHits>1000?1000:hits.totalHits; 
		//对pm对象设定属性
		pm.setDatas(list);
		pm.setTotal(totle);
		if(totle%length != 0){
			pm.setPageCount(totle/length+1);
		}else{
			pm.setPageCount(totle/length);
		}
		
		//关闭searcher和directory
		searcher.close();
		directory.close();
			
		 
		return pm;
		
	}
	
	
	
	
	
	
}
Global site tag (gtag.js) - Google Analytics