java Lucene搜索引擎

之前讲了一个java爬虫,接着java爬虫,可以再用java的lucene库实现一个小型的垂直式搜索引擎,简单来说就是通过爬虫将目标数据爬取到本地数据库,然后通过Lucene创建索引,进而就可以实现搜索引擎。先爬取数据,这里的数据源是一个论坛网站,爬虫使用之前介绍过的java爬虫, 思路就是访问网站,建立通道得到html源码,用正则表达式抽取目标数据,通过JDBC存入数据库。

package SpiderDemo;

import java.awt.AWTException;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.regex.*;

import javax.imageio.ImageIO;

class SpiderDemo{
	
	final static String CHARSET_STRING = "charset";   //charset网页编码方式
	static ArrayList<String> a = new ArrayList<String>();   //全局缓冲区,放置抓取数据
	static ArrayList<String> b = new ArrayList<String>();
	static ArrayList<String> c = new ArrayList<String>();
	static ArrayList<String> d = new ArrayList<String>();
	static ArrayList<String> e = new ArrayList<String>();
	static ArrayList<String> A = new ArrayList<String>();
	static ArrayList<String> B = new ArrayList<String>();
	static ArrayList<String> C = new ArrayList<String>();
	static ArrayList<String> D = new ArrayList<String>();
	static ArrayList<String> E = new ArrayList<String>();
	
	//正则表达式抓取网页编码,这里主要是测试正则表达式使用
	public static String GetCharset(String path) {
		
		URL pageURL = null;
		StringBuilder pageBuffer = null;
		String charSet = null;
		
		try {
			pageURL = new URL(path);
			BufferedReader reader = new BufferedReader(new InputStreamReader(pageURL.openStream()));
			String line;
			pageBuffer = new StringBuilder();
			while((line = reader.readLine())!=null){
				pageBuffer.append(line);
				}
		}
		catch(Exception e) {
			System.out.println("error0");
		}
		String content = pageBuffer.toString();
		//用正则表达式获取网页编码方式charset
		String regex1 = "char[sS]et=[^\\w]?([-\\w]+)";		
		Pattern p = Pattern.compile(regex1);
		Matcher m = p.matcher(content);
		if(m.find()) {
			charSet = m.group(1);
		}	
		return (charSet);
	}
	
	
	//获取网页html
	public static String DownloadPage(String path, String encoding) {
		
		URL pageURL = null;
		StringBuilder pageBuffer = null;
		
		try {
			pageURL = new URL(path);
			BufferedReader reader = new BufferedReader(new InputStreamReader(pageURL.openStream(),encoding));
			String line;
			pageBuffer = new StringBuilder();
			while((line = reader.readLine())!=null){
				pageBuffer.append(line);
				}
		}
		catch(Exception e) {
			System.out.println("error");
		}
		return pageBuffer.toString();
	}

	
	//将结果(String)写入本地txt文件
	public static void WriteDownloadPage(String str)
	{
		
		FileWriter fw = null;
		StringReader fr = null; 
		
		try{
			String fileName = "F:\\test.txt";  //本地地址
			fw = new FileWriter(fileName);
			fr = new StringReader(str);
			char[] ch = new char[1024];
			int length = 0;
			while((length=fr.read(ch))!=-1){
				fw.write(ch,0,length);
			}
		}
		catch(Exception e){
			System.out.println("error");
		}
		finally{
			if(fw!=null){
				try{
					fw.close();
				}
				catch(IOException e){
					System.out.println(e);
				}
			}
			if(fr!=null){
				try{
					fw.close();
				}
				catch(IOException e){
					System.out.println(e);
				}
			}
		}
	}
	
	//抓取论坛数据
	public static String BBSB(String source) {
		
		//创建动态数组
		ArrayList<String> title = new ArrayList<String>();
		ArrayList<String> author = new ArrayList<String>();
		ArrayList<String> link = new ArrayList<String>();
		ArrayList<String> time = new ArrayList<String>();
		ArrayList<String> view = new ArrayList<String>();
		
		
		//正则表达式获取帖子标题
		String regex1 = "resolved_warp\"><a.+?>(.+?)</a>     ";
		Pattern p1 = Pattern.compile(regex1);
		Matcher m1 = p1.matcher(source);
		for(;m1.find();) {
			title.add(m1.group(1));
		}
		
		
		//正则表达式获取帖子作者
		String regex2 = "resolved_warp\\\"><a.+?<p>(.+?)</p></a><a";
		Pattern p2 = Pattern.compile(regex2);
		Matcher m2 = p2.matcher(source);
		for(;m2.find();) {
			author.add(m2.group(1));
		}
		
		
		//正则表达式获取帖子链接
		String regex3 = "</p></a><a href=\"(.+?)\"";
		Pattern p3 = Pattern.compile(regex3);
		Matcher m3 = p3.matcher(source);
		for(;m3.find();) {
			link.add(m3.group(1));
		}
		
		
		//正则表达式获取发帖时间
		String regex4 = "time_ fr\"><span>(.+?)</sp";
		Pattern p4 = Pattern.compile(regex4);
		Matcher m4 = p4.matcher(source);
		for(;m4.find();) {
			time.add(m4.group(1));
		}

		//正则表达式获取帖子查看/回复量
		String regex5 = "</i><p>(.+?)</p>";
		Pattern p5 = Pattern.compile(regex5);
		Matcher m5 = p5.matcher(source);
		for(;m5.find();) {
			view.add(m5.group(1));
		}
		
		
		ArrayList<String> Result = new ArrayList<String>();  //创建Result,拼接数据,用以存入txt
		for(int i=0;i<title.size();i++) {
			Result.add("标题:"+title.get(i)+"  作者:"+author.get(i)+"  链接:"+link.get(i)+"  发帖时间:"+time.get(i)+"  查看量:"+view.get(i)+"\n");
			a.add(i,title.get(i));
			b.add(i,author.get(i));
			c.add(i,link.get(i));
			d.add(i,time.get(i));
			e.add(i,view.get(i));
		}
		String str= Result.toString();
		return str;
		}
	
	
	//论坛贴内数据抓取
	public static String BBSC(String source){

		//创建动态数组
		ArrayList<String> title = new ArrayList<String>();
		ArrayList<String> floornm = new ArrayList<String>();
		ArrayList<String> time = new ArrayList<String>();
		ArrayList<String> content = new ArrayList<String>();
		ArrayList<String> author = new ArrayList<String>();
		
		
		//正则表达式获取帖子标题
		String regex1 = "<title>(.+?)</title>";
		Pattern p1 = Pattern.compile(regex1);
		Matcher m1 = p1.matcher(source);
		for(;m1.find();) {
			title.add(m1.group(1));
		}
		
		
		//正则表达式获取讨论讨论楼层
		String regex2 = "floor-nm\">(.+?)</span>";
		Pattern p2 = Pattern.compile(regex2);
		Matcher m2 = p2.matcher(source);
		for(;m2.find();) {
			floornm.add(m2.group(1));
		}
		
		
		//正则表达式获取讨论时间
		String regex3 = "</span><span>(.+?)</span>";
		Pattern p3 = Pattern.compile(regex3);
		Matcher m3 = p3.matcher(source);
		for(;m3.find();) {
			time.add(m3.group(1));
		}
		
				
		//正则表达式获取讨论内容
		Pattern p4 = Pattern.compile("message\"><div class.+?</font><br />.+?<div class=\"quoteico_R\">.+?<br />(.+?)<br /></div>|message\">(.+?)</div>");
		Matcher m4 = p4.matcher(source);
		for(;m4.find();) {
			if(m4.group(1)!=null)
				content.add(m4.group(1));
			else if(m4.group(1)==null)
				content.add(m4.group(2));
		}
		
		
		//正则表达式获取讨论者
		String regex5 = "class=\"blue\">(.+?)</a>";
		Pattern p5 = Pattern.compile(regex5);
		Matcher m5 = p5.matcher(source);
		for(;m5.find();) {
			author.add(m5.group(1));
		}
		
		
		ArrayList<String> Result = new ArrayList<String>();  //创建Result,拼接数据,用以存入txt
		for(int i=0;i<min(floornm.size(),time.size(),content.size(),author.size());i++) {
			Result.add("标题:"+title.get(0)+"  作者:"+author.get(i)+"  楼层:"+floornm.get(i)+"  内容:"+content.get(i)+"  时间:"+time.get(i)+"\n");
			A.add(0,title.get(0));
			B.add(i,floornm.get(i));
			C.add(i,time.get(i));
			D.add(i,content.get(i));
			E.add(i,author.get(i));
		}
		String str= Result.toString();
		return str;
	}
	
	
	//数据库操作
	public static void Sql(){
		
		//声明Connection对象
		Connection con;
	    //驱动程序名
		String driver = "com.mysql.jdbc.Driver";
		//URL指向要访问的数据库csdnspider
		String url = "jdbc:mysql://localhost:3306/spider3DM";
		//MySQL配置时的用户名
		String user = "root";
		//MySQL配置时的密码
		String password = "root";
		
		try {
			//加载驱动程序
		    Class.forName(driver);
		    con = DriverManager.getConnection(url,user,password);
		    if(!con.isClosed())
		    	System.out.println("Succeeded connecting to the Database!");
		    PreparedStatement psql;
		    psql = con.prepareStatement("insert into taiwu3DM (title,author,link,time,view) "+"values(?,?,?,?,?)");
		    for(int i=0;i<a.size();i++)
		    { 	
		    	psql.setString(1, a.get(i));
		    	psql.setString(2, b.get(i));
		    	psql.setString(3, "http://bbs.3dmgame.com/"+c.get(i));  //拼接完整link
		    	psql.setString(4, d.get(i));
		    	psql.setString(5, e.get(i));
		    	psql.executeUpdate();  
		    }
	
		    for(int i = 0;i<B.size();i++)
		    {
			    psql = con.prepareStatement("insert into taiwu3DM2 (Title,floornm,Time,content,Author) "+"values(?,?,?,?,?)");
		    	psql.setString(1, A.get(i));
		    	psql.setString(2, B.get(i));
		    	psql.setString(3, C.get(i));
		    	psql.setString(4, D.get(i));
		    	psql.setString(5, E.get(i));
		    	psql.executeUpdate();
		    }
		        con.close();
		        } catch(ClassNotFoundException e) {   
		        //数据库驱动类异常处理
		        	System.out.println("Sorry,can`t find the Driver!");   
		            e.printStackTrace();   
		        } catch(SQLException e) {
		        //数据库连接失败异常处理
		        	e.printStackTrace();  
		        	}catch (Exception e) {
		             // TODO: handle exception
		            e.printStackTrace();
		         }finally{
		             System.out.println("Data successfully stored in database");
		             }
		}
	
	
	//该模块用于获取网页截图,生成快照
	public static void image() throws MalformedURLException, 
	IOException, URISyntaxException, AWTException{
		int i=117;
		for(;i<a.size();i++)
		{
		Desktop.getDesktop().browse(  
				new URL("http://bbs.3dmgame.com/"+c.get(i)).toURI());  
		Robot robot = new Robot();  
		robot.delay(5000);  
		Dimension d = new Dimension(Toolkit.getDefaultToolkit().getScreenSize());  
		int width = (int) d.getWidth();  
		int height = (int) d.getHeight();  
		robot.keyRelease(KeyEvent.VK_F11);  
		robot.delay(2000);  
		Image image = robot.createScreenCapture(new Rectangle(0, 0, width,  
				height));
		BufferedImage bi = new BufferedImage(width, height,  
				BufferedImage.TYPE_INT_RGB);  
		Graphics g = bi.createGraphics();  
		g.drawImage(image, 0, 0, width, height, null);   
		ImageIO.write(bi, "jpg", new File("f:/photo/"+i+".jpg"));  
		}
	}
	
	//main方法
	public static void main(String[] args){
		
		//抓取论坛文章
		String path = "http://bbs.3dmgame.com/forum-2803-1.html";
		String encoding = GetCharset(path);
		for(int i = 2;i < 20;i++) {
			String result = DownloadPage(path,encoding);
			path = "http://bbs.3dmgame.com/forum-2803-"+i+".html";
			BBSB(result);  //根据正则表达式获取数据
		}
		Sql();
		try {
			image();
		} catch (IOException | URISyntaxException | AWTException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
}

这里的java爬虫和先前的相比,增加了一个通过java awt实现网页截图的函数,将截图作为搜索引擎的网页快照,对应的,需要增加抓取的间隔时延,否则太快会导致截图出现问题,因此需要delay一段时间。

这样就获得了需要的各类数据项,以及网页的截图文件,然后就是写java web,这里用得是最简单的jsp和servlet的结构,用框架也可以。

创建索引部分

package index;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.DateField;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;

import common.Constant;

public class CreateIndexServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public CreateIndexServlet() {
		super();
	}

	public void destroy() {
		super.destroy();
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		response.setContentType("text/html");
		// 设置发送到客户端的响应的内容类型,此时响应还没有提交
		PrintWriter out = response.getWriter();
		// response:服务器对浏览器的相应,PrintWriter它的实例就是向前台的JSP页面输出结果
		String indexPath = "F:\\pachong\\index";

		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;

		try {

			IndexWriter writer = new IndexWriter(Constant.INDEX_PATH, new StandardAnalyzer(), true);
			// 索引存放地址,分析器,IndexWriter 不管目录内是否已经有索引了,一律清空,重新建立
			Class.forName("com.mysql.jdbc.Driver").newInstance();
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/spider3dm?user=root&password=root");
			stmt = conn.createStatement();
			rs = stmt.executeQuery("select * from taiwu3dm order by id");
			while (rs.next()) {
				System.out.println(rs.getRow());
				Document doc = new Document();
				String title = rs.getString("title");
				String path = "F:\\index\\" + rs.getInt("id") + ".txt";
				String id = Integer.toString(rs.getInt("id"));
				Field idFld = new Field("id", id, Field.Store.YES, Field.Index.NO);
				Field titleFld = new Field("title", title, Field.Store.YES, Field.Index.TOKENIZED);
				Field titleFld2 = new Field("title2", title, Field.Store.YES, Field.Index.UN_TOKENIZED);
				Field linkFld = new Field("link", rs.getString("link"), Field.Store.YES, Field.Index.NO);
				Field authorFld = new Field("author", rs.getString("author"), Field.Store.YES, Field.Index.TOKENIZED);
				Field timeFld = new Field("time", rs.getString("time"), Field.Store.YES, Field.Index.UN_TOKENIZED);
				Field viewFld = new Field("view", rs.getString("view"), Field.Store.YES, Field.Index.TOKENIZED);
				// Index.NO 不需要索引;Index.TOKENIZED
				// 先被分词再被索引;Index.UN_TOKENIZED被索引但不会被分词
				
				doc.add(idFld);
				doc.add(titleFld);
				doc.add(titleFld2);
				doc.add(linkFld);
				doc.add(timeFld);
				doc.add(authorFld);
				doc.add(viewFld);
				writer.addDocument(doc);
			}
			writer.optimize();// 对索引进行优化
			writer.close();// 关闭写入流对象并将索引写入目录
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException ex) {
			ex.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (Exception e) {
			System.out.println(e);
		} finally {
			try {
				if (rs != null) {
					rs.close();
					rs = null;
				}
				if (stmt != null) {
					stmt.close();
					stmt = null;
				}
				if (conn != null) {
					conn.close();
					conn = null;
				}
			} catch (SQLException ex) {
				ex.printStackTrace();
			}
		}

		out.flush();
		out.close();
	}

	public void init() throws ServletException {
	}

}

这里需要注意的是索引的几种类型,即是否需要分词、是否需要索引,这会影响后面的检索。

可以定义一个common包来存放通用变量,比如路径。

package common;
import org.apache.lucene.store.Directory;

public class Constant {
	public final static String FILE_PATH = "F:\\file\\";
	public final static String INDEX_PATH = "F:\\index";
}

然后就是检索的servlet文件。

package search;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;

import common.Constant;

public class SimpleSearchServlet extends HttpServlet {

	public SimpleSearchServlet() {
		super();
	}

	public void destroy() {
		super.destroy();
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 简单查询页面对应Servlet,这里直接使用MultiFieldQueryParser,兼具多域查询功能和QueryParser的关键词转换功能。

		request.setCharacterEncoding("UTF-8");
		String txt = request.getParameter("txt");
		// 建立MultiFieldQueryParser多域查询
		String[] fields = { "title", "author" };
		MultiFieldQueryParser mp = new MultiFieldQueryParser(fields, new StandardAnalyzer());
		System.out.println(txt);
		Query query = null;
		try {
			query = mp.parse(txt); 
		// 未指明传入布尔关系时,默认为SHOULD,也就是说这里是指在标题或在正文里出现
		} catch (ParseException e) {
			e.printStackTrace();
		}
		System.out.println(query);
		IndexSearcher indexSearcher = new IndexSearcher(Constant.INDEX_PATH);
		Hits hits = indexSearcher.search(query);
		// hits是存放有序搜索结果指针的简单容器。检索结果是指匹配一个已知查询的一系列文档
		//System.out.println(hits.length());
		request.setAttribute("flag", "simpleSearch");
		request.setAttribute("hits", hits);
		request.setAttribute("txt", txt);
		RequestDispatcher rd = request.getRequestDispatcher("result.jsp");
		rd.forward(request, response);
	}

	public void init() throws ServletException {
	}

}

简单查询功能,对多个域进行普通检索。

package search;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RangeQuery;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.regex.RegexQuery;
import org.apache.lucene.search.spans.SpanNearQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.apache.lucene.*;

import common.Constant;

public class JuniorSearchServlet extends HttpServlet {

public JuniorSearchServlet() {
    super();
}

public void destroy() {
    super.destroy();

}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    doPost(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.setCharacterEncoding("UTF-8");

    //获取热门搜索,预定义
    String channelid = request.getParameter("channelid");
    System.out.println("channelid:"+channelid);


    //获取跨度检索关键词A、B
    String txt4 = request.getParameter("txt4");
    String txt5 = request.getParameter("txt5");


    //获取日期查询的起止年月日,并组合成索引中的格式
    String time_begin_year = request.getParameter("time_begin_year");
    String time_begin_month = request.getParameter("time_begin_month");
    String time_begin_day = request.getParameter("time_begin_day");
    String time_end_year = request.getParameter("time_end_year");
    String time_end_month = request.getParameter("time_end_month");
    String time_end_day = request.getParameter("time_end_day");
    String time_begin = time_begin_year+"-"+time_begin_month+"-"+time_begin_day;
    String time_end = time_end_year+"-"+time_end_month+"-"+time_end_day;

    //获取作者查询的作者名,并且获取使用模糊或精准查询
    String authorsearch = request.getParameter("authorsearch");
    String fuzzy_author = request.getParameter("fuzzy_author");


    //获取前缀查询的短语,并且获取bool值
    String prefixsearch = request.getParameter("prefixsearch");
    String boolean_prefix = request.getParameter("boolean_prefix");

    //获取通配符查询的短语,并且获取bool值
    String wildcardsearch = request.getParameter("wildcardsearch");
    String boolean_wildcard = request.getParameter("boolean_wildcard");

    //获取正则表达式
    String regexsearch = request.getParameter("regexsearch");
    String boolean_regex = request.getParameter("boolean_regex");

    //获取时间排序
    String time_sort = request.getParameter("time_sort");
    //获取得分排序
    String score_sort = request.getParameter("score_sort");
    //获取浏览量排序
    String view_sort = request.getParameter("view_sort");

    /*
     * 生成总bool检索
     */
    BooleanQuery bool = new BooleanQuery();     


    /*
     * 功能1:
     * 热门搜索查询
     * 使用多域查询,布尔判断为SHOULD
     * 预定义热门话题检索
     */
    String[] fields = { "title", "author", "link", "time" };
    MultiFieldQueryParser mp = new MultiFieldQueryParser(fields, new StandardAnalyzer());
    Query query1 = null;
    try {
        query1 = mp.parse(channelid);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    if(!channelid.equals("0"))
        bool.add(query1, BooleanClause.Occur.MUST);  //将query1加入bool


    /*
     * 功能2:
     * 前缀查询
     * 选择并含、或含、不含关系
     */
    System.out.println("prefixsearch:"+prefixsearch);
    if (!prefixsearch.isEmpty()) {
        Term Term1 = new Term("title2", prefixsearch);
        PrefixQuery query2 = new PrefixQuery(Term1);
        if (boolean_prefix.equals("1")) {
            bool.add(query2, BooleanClause.Occur.MUST);  //并含
        } else if (boolean_prefix.equals("2")) {
            bool.add(query2, BooleanClause.Occur.SHOULD);  //或含
        } else {
            bool.add(query2, BooleanClause.Occur.MUST_NOT);  //不含
        }
    }


    /*
     * 功能3:
     * 通配符查询
     * 选择并含、或含、不含关系
     */
    System.out.println("wildcardsearch:"+wildcardsearch);
    if (!wildcardsearch.isEmpty()) {
        Term Term1 = new Term("title", wildcardsearch);
        WildcardQuery query3 = new WildcardQuery(Term1);
        if (boolean_wildcard.equals("1")) {
            bool.add(query3, BooleanClause.Occur.MUST);  //并含
        } else if (boolean_wildcard.equals("2")) {
            bool.add(query3, BooleanClause.Occur.SHOULD);  //或含
        } else {
            bool.add(query3, BooleanClause.Occur.MUST_NOT);  //不含
        }
    }


    /*
     * 功能4:
     * 时间查询
     * 使用范围查找控制时间范围
     */
    if ((!time_begin.isEmpty()) || (!time_end.isEmpty())) {
        Term begintime = new Term("time", time_begin);
        Term endtime = new Term("time", time_end);
        RangeQuery query4 = new RangeQuery(begintime, endtime, true);
        System.out.println(query4.toString());
        bool.add(query4, BooleanClause.Occur.MUST);  //对应时间范围
        System.out.println("时间范围查询语句显示:" + query4.toString());
    }


    /*
     * 功能5:
     * 作者查询、模糊精准查询
     * 选择进行模糊Fuzzy/精准关键词查询Term
     * test:wanzhou
     */
    if (!authorsearch.isEmpty()) {
        Term Term5 = new Term("author", authorsearch);
        Query query5 = null;
        if (fuzzy_author.equals("2")) {
            query5 = new FuzzyQuery(Term5,0.2f,6);   //前缀6、模糊程度取0.2
        } else {
            query5 = new TermQuery(Term5);
        }
        bool.add(query5, BooleanClause.Occur.MUST);// 对应作者
        System.out.println("作者查询语句显示2:" + query5.toString());
    }


    /*
     * 功能6:
     * 正则表达式检索
     * 
     */
    System.out.println("regexsearch:" + regexsearch);
    if(!regexsearch.isEmpty()) {
        Term Term6 = new Term("title",regexsearch);
        RegexQuery query6 = new RegexQuery(Term6);
        if (boolean_regex.equals("1")) {
            bool.add(query6, BooleanClause.Occur.MUST);  //并含
        } else if (boolean_regex.equals("2")) {
            bool.add(query6, BooleanClause.Occur.SHOULD);  //或含
        } else {
            bool.add(query6, BooleanClause.Occur.MUST_NOT);  //不含
        }
    }

    /*
     * 功能:7
     * 排序条件下检索
     * 关联性得分排序、时间排序、浏览量排序
     */
    //时间排序
    SortField f1 = null;
    if(!time_sort.equals("0")) {
        if(time_sort.equals("1")) {
            f1 = new SortField("time",SortField.STRING,true);
        } else if(time_sort.equals("2")) {
            f1 = new SortField("time",SortField.STRING);
        }
    } 
    //得分排序
    SortField f2 = null;
    if(!score_sort.equals("0")) {
        if(score_sort.equals("1")) {
            f2 = new SortField("title",SortField.SCORE);
        }else if(score_sort.equals("2")) {
            f2 = new SortField("title",SortField.SCORE,true);
        }
    }
    //浏览量排序
    SortField f3 = null;
    if(!view_sort.equals("0")) {
        if(view_sort.equals("1")) {
            f3 = new SortField("view",SortField.INT,true);
        }else if(view_sort.equals("2")) {
            f3 = new SortField("view",SortField.INT);
        }
    }
    //创建搜索器,对bool进行搜索
    IndexSearcher indexSearcher = new IndexSearcher(Constant.INDEX_PATH);
    Sort sort = null;
    Hits hits = null;
    //判断是否需要使用排序,如不排序,默认为以关联性得分为标准排序;当存在多个排序条件时,优先顺序为浏览量、关联性得分、时间
    if(time_sort.equals("0") && score_sort.equals("0") && view_sort.equals("0")) {
        hits = indexSearcher.search(bool);
    } else if(time_sort.equals("0") && (!score_sort.equals("0")) && (!view_sort.equals("0"))) {
        sort = new Sort(new SortField[] {f3,f2});
        hits = indexSearcher.search(bool,sort);
    } else if(score_sort.equals("0") && (!time_sort.equals("0")) && (!view_sort.equals("0"))) {
        sort = new Sort(new SortField[] {f3,f1});
        hits = indexSearcher.search(bool,sort);
    } else if(view_sort.equals("0") && (!time_sort.equals("0")) && (!score_sort.equals("0"))) {
        sort = new Sort(new SortField[] {f2,f1});
        hits = indexSearcher.search(bool,sort);
    } else if(!time_sort.equals("0")) {
        sort = new Sort(new SortField[] {f1});
        hits = indexSearcher.search(bool,sort);
    } else if(!score_sort.equals("0")) {
        sort = new Sort(new SortField[] {f2});
        hits = indexSearcher.search(bool,sort);
    } else if(!view_sort.equals("0")) {
        sort = new Sort(new SortField[] {f3});
        hits = indexSearcher.search(bool,sort);
    } else {
        sort = new Sort(new SortField[] {f3,f2,f1});
        hits = indexSearcher.search(bool,sort);
    }


    //结果打印,检索条件输出
    System.out.println("查询结果数为:" + hits.length());
    request.setAttribute("flag", "juniorSearch");
    request.setAttribute("hits", hits);
    request.setAttribute("score_sort", score_sort);
    HttpSession session = request.getSession(); 
    session.setAttribute("channelid",channelid);
    session.setAttribute("time_begin_year",time_begin_year);
    session.setAttribute("time_begin_month",time_begin_month);
    session.setAttribute("time_begin_day",time_begin_day);
    session.setAttribute("time_end_year",time_end_year);
    session.setAttribute("time_end_month",time_end_month);
    session.setAttribute("time_end_day",time_end_day);
    session.setAttribute("authorsearch",authorsearch);
    session.setAttribute("fuzzy_author",fuzzy_author);
    session.setAttribute("prefixsearch",prefixsearch);
    session.setAttribute("boolean_prefix",boolean_prefix);
    session.setAttribute("wildcardsearch",wildcardsearch);
    session.setAttribute("boolean_wildcard",boolean_wildcard);
    session.setAttribute("regexsearch",regexsearch);
    session.setAttribute("boolean_regex",boolean_regex);
    RequestDispatcher rd = request.getRequestDispatcher("result.jsp");
    rd.forward(request, response);

  }

  public void init() throws ServletException {

  }

}

高级检索功能,包括多域热门检索、前缀检索、通配符查询、时间查询、作者查询、正则表达式查询、排序等。

package search;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;

import common.Constant;

public class clearServlet extends HttpServlet {

	public clearServlet() {
		super();
	}

	public void destroy() {
		super.destroy();
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		session.removeAttribute("channelid");
		session.removeAttribute("time_begin_year");
		session.removeAttribute("time_begin_month");
		session.removeAttribute("time_begin_day");
		session.removeAttribute("time_end_year");
		session.removeAttribute("time_end_month");
		session.removeAttribute("time_end_day");
		session.removeAttribute("authorsearch");
		session.removeAttribute("fuzzy_author");
		session.removeAttribute("prefixsearch");
		session.removeAttribute("boolean_prefix");
		session.removeAttribute("wildcardsearch");
		session.removeAttribute("boolean_wildcard");
		session.removeAttribute("regexsearch");
		session.removeAttribute("boolean_regex");
		RequestDispatcher rd = request.getRequestDispatcher("index.jsp");
		rd.forward(request, response);
	}

	public void init() throws ServletException {
	}

}

清除session,把缓存都清除。

package search;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.DateField;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;

import com.mysql.jdbc.PreparedStatement;

import common.Constant;

public class CollectionServlet extends HttpServlet {


	private static final long serialVersionUID = 1L;

	public CollectionServlet(){
		super();
	}

	public void destroy() {
		super.destroy();
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setCharacterEncoding("utf-8");
		String t = request.getParameter("id");
		response.setContentType("text/html");
		// 设置发送到客户端的响应的内容类型,此时响应还没有提交
		PrintWriter out = response.getWriter();
		// response:服务器对浏览器的相应,PrintWriter它的实例就是向前台的JSP页面输出结果
			String driver = "com.mysql.jdbc.Driver";
			String url = "jdbc:mysql://127.0.0.1:3306/spider3dm";
			String user = "root";
			String password = "root";
			try {
				Class.forName(driver);
				Connection conn = DriverManager.getConnection(url, user, password);
				Statement statement = conn.createStatement();
				String sql = "INSERT INTO Collection (title,view,author,time,link) SELECT title,view,author,time,link FROM taiwu3dm where id = '"+t+"'";
				statement.executeUpdate(sql);
				conn.close();
				}catch (ClassNotFoundException e){
					System.out.println("Sorry,can`t find the Driver!");
					e.printStackTrace();
					} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} 
		RequestDispatcher dipactch =request.getRequestDispatcher("collection.jsp");
		 dipactch.forward(request,response);
	}

	public void init() throws ServletException {
	}

}

收藏功能,这里使用JDBC把用户选择的项目存入该用户的收藏夹中。

package search;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RangeQuery;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.regex.RegexQuery;
import org.apache.lucene.search.spans.SpanNearQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.apache.lucene.*;

import common.Constant;

public class MatchAllDocsServlet extends HttpServlet {

	public MatchAllDocsServlet() {
		super();
	}

	public void destroy() {
		super.destroy();

	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");	
		Query query = new MatchAllDocsQuery();
		IndexSearcher indexSearcher = new IndexSearcher(Constant.INDEX_PATH);
		Hits hits = null;
		hits = indexSearcher.search(query);
		System.out.println("查询结果数为:" + hits.length());
		request.setAttribute("flag", "juniorSearch");
		request.setAttribute("hits", hits);
		RequestDispatcher rd = request.getRequestDispatcher("result.jsp");
		rd.forward(request, response);
		}

	public void init() throws ServletException {

	}

}

全文档查询

package search;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RangeQuery;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.regex.RegexQuery;
import org.apache.lucene.search.spans.SpanNearQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.apache.lucene.*;

import common.Constant;

public class MultiFieldQueryParserServlet extends HttpServlet {

	public MultiFieldQueryParserServlet() {
		super();
	}

	public void destroy() {
		super.destroy();

	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		
		//获取多词检索关键词
		String txt1 = request.getParameter("txt1");
		String txt2 = request.getParameter("txt2");
		String txt3 = request.getParameter("txt3");

		/*
		 * 生成总bool检索
		 */
		BooleanQuery bool = new BooleanQuery();		
		
		/*
		 * 功能7:
		 * 用户自定义多个关键词检索,取并集
		 * test:1、2、3
		 */
		if(!(txt1==null&&txt2==null&&txt3==null)) {
		MultiPhraseQuery query7 = new MultiPhraseQuery();
		Term t1 = new Term ("title", txt1);
		Term t2 = new Term ("title", txt2);
		Term t3 = new Term ("title", txt3);
		query7.add (new Term[] {t1,t2,t3});
		bool.add(query7, BooleanClause.Occur.MUST);  //将query1加入bool
		}

		//创建搜索器,对bool进行搜索
		IndexSearcher indexSearcher = new IndexSearcher(Constant.INDEX_PATH);
		Hits hits = null;
		hits = indexSearcher.search(bool);
		System.out.println("查询结果数为:" + hits.length());
		request.setAttribute("flag", "juniorSearch");
		request.setAttribute("hits", hits);
		RequestDispatcher rd = request.getRequestDispatcher("result.jsp");
		rd.forward(request, response);
		}

	public void init() throws ServletException {

	}

}

用户自定义关键词,在多个索引域上检索,结果取并集。

package search;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RangeQuery;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.regex.RegexQuery;
import org.apache.lucene.search.spans.SpanFirstQuery;
import org.apache.lucene.search.spans.SpanNearQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.apache.lucene.*;

import common.Constant;

public class spantServlet extends HttpServlet {

	public spantServlet() {
		super();
	}

	public void destroy() {
		super.destroy();

	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		
		//获取多词检索关键词
		String txt7 = request.getParameter("txt7");
		String txt6 = request.getParameter("txt6");
		int span = Integer.parseInt(txt6);

		/*
		 * 生成总bool检索
		 */
		BooleanQuery bool = new BooleanQuery();		
		
		/*
		 * 功能8:
		 * 跨度查询
		 */
		if(txt7!=null) {
		 String queryStringStart = txt7;   
	     SpanQuery queryStart = new SpanTermQuery(new Term("title",queryStringStart)); 
	     SpanFirstQuery sfq=new SpanFirstQuery(queryStart,span);
	     bool.add(sfq,BooleanClause.Occur.MUST);
		}

		//创建搜索器,对bool进行搜索
		IndexSearcher indexSearcher = new IndexSearcher(Constant.INDEX_PATH);
		Hits hits = null;
		hits = indexSearcher.search(bool);
		System.out.println("查询结果数为:" + hits.length());
		request.setAttribute("flag", "juniorSearch");
		request.setAttribute("hits", hits);
		RequestDispatcher rd = request.getRequestDispatcher("result.jsp");
		rd.forward(request, response);
		}

	public void init() throws ServletException {

	}

}

跨度查询,用户给定查询跨度的长度。

以上就是后端的部分,主要是调用了Lucene的一些检索功能,具体的可以查看lucene文档,不同版本的检索功能和参数都不太一样,主要是索引创建、指定域检索、多域检索、排序、模糊检索、前缀检索、通配符检索、正则符检索这些比较重要。然后前端页面用jsp写的,如下。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>BBS检索</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
</head>
<script>
	var request = false;
	try {
		request = new XMLHttpRequest();
	} catch (trymicrosoft) {
		try {
			request = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (othermicrosoft) {
			try {
				request = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (failed) {
				request = false;
			}
		}
	}

	if (!request)
		alert("Error initializing XMLHttpRequest!");

	function createIndex() {
		var url = "CreateIndexServlet";
		request.open("post", url, true);
		request.onreadystatechange = returnMessage;
		request.send(null);
	}

	function returnMessage() {
		if (request.readyState == 4) {
			if (request.status == 200) {
				var response = request.responseText;
				alert("索引创建成功!");
			} else
				alert("status is " + request.status);
		}
	}
</script>

<body background="D:\java\javaee-workspace\test\background.jpg" style=" background-repeat:no-repeat ;
background-size:100% 100%;
background-attachment: fixed;">
	<center>
		<div style="height: 400px; width: 800px;padding-top:120px;">
			<div style="height: 100px; width: 800px"></div>
			&nbsp;
			<img  src="D:\java\javaee-workspace\test\检索.png" />
			<form action="SimpleSearchServlet" method="post">
				<input type="text" name="txt" id="txt"
					style="height: 30px; width: 500px; background-color: rgba(0,0,1,0.3);border:none;color:white"> <input type="submit"
					value="搜索" style="height: 30px; width: 80px;background-color: rgba(0,0,1,0.3);border:none;color:white">
				<input type="button" onclick="window.location.href='jiansuo.jsp'" value="高级检索"
					style="height: 30px; width: 80px; font-family: 黑体; color:white;background-color: rgba(0,0,1,0.3);border:none">
				<input type="button" value="创建索引"
				    style="height: 30px; width: 80px;background-color: rgba(0,0,1,0.3);border:none;color:white" onclick="createIndex()">
			</form>
		</div>
		&nbsp;
	</center>

	<input type="button" onclick="window.location.href='history.jsp'" value="检索历史"
			style="height: 30px; width: 80px; font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;top:20px;left:50px">
	<form action="Top10Servlet" method="post">
	<input type="button" onclick="window.location.href='top10.jsp'" value="热门话题"
			style="height: 30px; width: 80px; font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;top:60px;left:50px">
    </form>
    <input type="button" onclick="window.location.href='collection.jsp'" value="我的收藏"
			style="height: 30px; width: 80px; font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;top:100px;left:50px">
	<form action="clearServlet" method="post" style="top:20px;margin-left:1250px">
	<input type="submit"
			value="清除当前高级检索式缓存" style="height: 30px; width: 170px;font-family: 楷体;background-color: rgba(0,0,1,0.3);border:none;color:white;position:fixed;top:20px;right:50px">
	</form>
	<input type="button" onclick="window.location.href='functionList.jsp'" value="高级功能"
			style="height: 30px; width: 80px; font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;top:60px;right:50px">
</body>
</html>

首页部分

<%@ page import="java.sql.*" %>
<%@ page contentType="text/html; charset=utf-8"%>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page language="java" import="org.apache.lucene.search.Hits"%>
<%@ page language="java" import="org.apache.lucene.document.Document"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
 	int Page = 0;
 	int end;
 	int k;
    ArrayList<String> Title = new ArrayList<String>();
    ArrayList<String> Link = new ArrayList<String>();
    ArrayList<String> Author = new ArrayList<String>();
    ArrayList<String> Time = new ArrayList<String>();
    ArrayList<Integer> View = new ArrayList<Integer>();
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>我的收藏</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>

<body background="D:\java\javaee-workspace\test\background3.jpg"style=" background-repeat:no-repeat ;
background-size:100% 100%;
background-attachment: fixed;">
  
  <% 
	String driver = "com.mysql.jdbc.Driver";
	// URL指向要访问的数据库名test1
	String url = "jdbc:mysql://127.0.0.1:3306/spider3dm";
	// MySQL配置时的用户名
	String user = "root";
	// Java连接MySQL配置时的密码
	String password = "root";
	try {
		// 1 加载驱动程序
		Class.forName(driver);
		// 2 连接数据库
		Connection conn = DriverManager.getConnection(url, user, password);
		// 3 用来执行SQL语句
		Statement statement = conn.createStatement();
		// 要执行的SQL语句
		String sql = "SELECT title,view,author,time,link FROM collection";
		ResultSet rs = statement.executeQuery(sql);
		String name = null;
		String mima=null;
		while(rs.next()){
			Title.add(rs.getString("title"));
			Author.add(rs.getString("author"));
			Link.add(rs.getString("link"));
			Time.add(rs.getString("time"));
			View.add(rs.getInt("view"));
		}
		rs.close();
		conn.close();
		} catch (ClassNotFoundException e) {
			System.out.println("Sorry,can`t find the Driver!");
			e.printStackTrace();
			} 
	%>
  
	<ul>
	<%
	for(k=0;k<Link.size();k++){
	%>
		<li>
		<a href="<%=Link.get(k)%>" style="color: white;"><%=k+1%>:<%=Title.get(k)%></a><br />
		<span style="color: white;"><a>作者:<%=Author.get(k)%></a></span><br />
		<span style="color: white;"><a>发布时间:<%=Time.get(k)%></a></span><br />
		<span style="color: white;"><a>浏览量:<%=View.get(k) %></a></span>
		</li>
		<br />
		<%
			}
		%>
		<center>
		<input type="button" onclick="window.location.href='index.jsp'" value="返回" 
					style="height: 30px; width: 80px; font-family: 楷体; color:white;background-color: #949449;border:none;position:fixed;top:50px;left:1270px">
        </center>
	</ul>
</body>
</html>

用户收藏

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>高级功能</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>

<body background="D:\java\javaee-workspace\test\background2.jpg"style=" background-repeat:no-repeat ;
background-size:100% 100%;
background-attachment: fixed;">
	<center>
		<input type="button" onclick="window.location.href='KeywordsQuery.jsp'" value="用户自定义多关键词查询"
			style="height: 30px; width: 180px; font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;top:20px;left:50px">
		<input type="button" onclick="window.location.href='spanQuery.jsp'" value="多词跨度查询"
			style="height: 30px; width: 180px; font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;top:60px;left:50px">
		<input type="button" onclick="window.location.href='spantQuery.jsp'" value="单词跨度查询"
			style="height: 30px; width: 180px; font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;top:100px;left:50px">
		<input type="button" onclick="window.location.href='MatchAllDocsQuery.jsp'" value="索引库查询"
			style="height: 30px; width: 180px; font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;top:140px;left:50px">
	</center>
	<center>
		<input type="button" onclick="window.location.href='index.jsp'" value="返回" 
					style="height: 30px; width: 80px; font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;bottom:50px;left:712px">
        </center>
</body>
</html>

功能列表

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>历史记录</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
</head>
<body background="D:\java\javaee-workspace\test\background.jpg"style=" background-repeat:no-repeat ;
background-size:100% 100%;
background-attachment: fixed;">
    <%!
    String h[]={null,null,null,null,null,null,null,null,null,null};
    %>
	<% 
	String H = (String)session.getAttribute("history");
	if(H!=h[0]){
	for(int i=h.length-1;i>0;i--){
		h[i]=h[i-1];
	}
	h[0]=H;}
	%>
	<%
	for(int I=0;I<h.length;I++){
		if(h[I]!=null){
		%>
	<li>
	<span style="color: white;"><a><%=I+1%>:<%=h[I] %></a></span><br \>
	</li>
	<%
		}
		}
	%>
	<center>
		<input type="button" onclick="window.location.href='index.jsp'" value="返回" 
					style="height: 30px; width: 80px; font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;bottom:50px;left:712px">
        </center>
</body>
</html>

用户历史查询记录,通过session实现。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>高级检索</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>

<body background="D:\java\javaee-workspace\test\background2.jpg"style=" background-repeat:no-repeat ;
background-size:100% 100%;
background-attachment: fixed;">
	<center>
		<img  src="D:\java\javaee-workspace\test\检索2.png" style="padding-top:20px"/>
	    <h3 style="font-family: 楷体;color:white;padding-top:20px">选择内容检索</h3>
		<form action="<%=path %>/JuniorSearchServlet" method="post" style="font-family: 楷体;color:white;">
			热门话题:<select name="channelid"
				style="width: 100px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 500;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option value="0" selected=''>请选择</option>
				<option>mod</option>
				<option>资源</option>
				<option>讨论</option>
				<option>视频</option>
				<option>求助</option>
				<option>分享</option>
			</select>&nbsp; 

			<h3>输入内容检索</h3>
			<!-- 以下是前缀搜索 -->
			前缀查询:&nbsp;<input type="text" id="prefixsearch" name="prefixsearch" style="color:white;background-color: rgba(0,0,1,0.3);border:none"/> 
			<select id="boolean_prefix" name="boolean_prefix" style="width: 100px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 500;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option value='1' selected=''>并含</option>
				<option value='2'>或含</option>
				<option value='3'>不含</option>
			</select>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
			<!-- 以上是前缀搜索 -->

			<!-- 以下是通配符搜索 -->
			通配符查询:<input type="text" id="wildcardsearch" name="wildcardsearch" style="color:white;background-color: rgba(0,0,1,0.3);border:none"/>
			<select id="boolean_wildcard" name="boolean_wildcard" style="width: 100px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 500;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option value='1' selected=''>并含</option>
				<option value='2'>或含</option>
				<option value='3'>不含</option>
			</select>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
			<!-- 以上是通配符搜索 -->
            
            
            <!-- 以下是正则表达式搜索 -->
               正则表达式查询: <input type="text" id="regexsearch" name="regexsearch" style="color:white;background-color: rgba(0,0,1,0.3);border:none"/>
			<select id="boolean_regex" name="boolean_regex" style="width: 100px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 500;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option value='1' selected=''>并含</option>
				<option value='2'>或含</option>
				<option value='3'>不含</option>
			</select>
            <!-- 以上是正则表达式搜索 -->
			
			
			<!-- 以下是作者搜索 -->
			<h3>精准or模糊检索</h3>
			作者:<input type="text" name="authorsearch" id="authorsearch"
				style="height: 25px; width: 196px;color:white;background-color: rgba(0,0,1,0.3);border:none" /> <select id="fuzzy_author"
				name="fuzzy_author" onchange="disableWordTimes(this);return false;"
				style="width: 100px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 500;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option value='1' selected=''>精确</option>
				<option value='2'>模糊</option>
			</select> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
			
			<!-- 以上是作者搜索 --> 
			
			
			<h3>输入范围检索</h3>
			<!-- 以下是时间范围搜索 -->
			时间:<span id="publishdate"> 
			<lable>从</lable> 
			<select name="time_begin_year"
				style="width: 70px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 400;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option selected=''>2015</option>
				<option>2016</option>
				<option>2017</option>
				<option>2018</option>
				<option>2019</option>
			</select> 
			<lable>年</lable>
			<select name="time_begin_month"
				style="width: 70px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 400;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option selected=''>01</option>
				<option>02</option>
				<option>03</option>
				<option>04</option>
				<option>05</option>
				<option>06</option>
				<option>07</option>
				<option>08</option>
				<option>09</option>
				<option>10</option>
				<option>11</option>
				<option>12</option>
			</select> 
			<lable>月</lable>
			<select name="time_begin_day"
				style="width: 70px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 400;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option selected=''>01</option>
				<option>02</option>
				<option>03</option>
				<option>04</option>
				<option>05</option>
				<option>06</option>
				<option>07</option>
				<option>08</option>
				<option>09</option>
				<option>10</option>
				<option>11</option>
				<option>12</option>
				<option>13</option>
				<option>14</option>
				<option>15</option>
				<option>16</option>
				<option>17</option>
				<option>18</option>
				<option>19</option>
				<option>20</option>
				<option>21</option>
				<option>22</option>
				<option>23</option>
				<option>24</option>
				<option>25</option>
				<option>26</option>
				<option>27</option>
				<option>28</option>
				<option>29</option>
				<option>30</option>
				<option>31</option>
			</select> 
			<lable>日</lable>
			&nbsp;&nbsp;<lable>到</lable>
			<select name="time_end_year"
				style="width: 70px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 400;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option selected=''>2019</option>
				<option>2018</option>
				<option>2017</option>
				<option>2016</option>
				<option>2015</option>
			</select> 
			<lable>年</lable>
			<select name="time_end_month"
				style="width: 70px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 400;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option selected=''>12</option>
				<option>01</option>
				<option>02</option>
				<option>03</option>
				<option>04</option>
				<option>05</option>
				<option>06</option>
				<option>07</option>
				<option>08</option>
				<option>09</option>
				<option>10</option>
				<option>11</option>
				<option>12</option>
			</select> 
			<lable>月</lable>
			<select name="time_end_day"
				style="width: 70px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 400;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option selected=''>31</option>
				<option>01</option>
				<option>02</option>
				<option>03</option>
				<option>04</option>
				<option>05</option>
				<option>06</option>
				<option>07</option>
				<option>08</option>
				<option>09</option>
				<option>10</option>
				<option>11</option>
				<option>12</option>
				<option>13</option>
				<option>14</option>
				<option>15</option>
				<option>16</option>
				<option>17</option>
				<option>18</option>
				<option>19</option>
				<option>20</option>
				<option>21</option>
				<option>22</option>
				<option>23</option>
				<option>24</option>
				<option>25</option>
				<option>26</option>
				<option>27</option>
				<option>28</option>
				<option>29</option>
				<option>30</option>
				<option>31</option>s
			</select> 
			<lable>日</lable>
			</span>
			<!-- 以上是时间范围搜索 -->
			<br />
			
			
			
			<h3>排序条件设置</h3>
			浏览量:<span>
			<select name="view_sort"
				style="width: 70px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 400;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option value='0' select=''>无</option>
				<option value='1'>降序</option>
				<option value='2'>升序</option>
			</select> 
			</span>&nbsp;
			得分:<span>
			<select name="score_sort"
				style="width: 70px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 400;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option value='0' select=''>无</option>
				<option value='1'>降序</option>
				<option value='2'>升序</option>
			</select> 
			</span>&nbsp;
			时间:<span>
			<select name="time_sort"
				style="width: 70px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 400;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option value='0' selected=''>无</option>
				<option value='1'>降序</option>
				<option value='2'>升序</option>
			</select> 
			</span>
			【优先次序为从左到右】
	</center>
	    <center>
			<p style="padding-top:20px;">
				<input type="submit" value="搜索"
					style="height: 30px; width: 80px; font-family: 黑体; color:white;background-color: rgba(0,0,1,0.3);border:none">
				<input type="button" onclick="window.location.href='jiansuo.jsp'" value="重置条件"
					style="height: 30px; width: 80px; font-family: 黑体; color:white;background-color: rgba(0,0,1,0.3);border:none">
				<input type="button" onclick="window.location.href='index.jsp'" value="返回"
					style="height: 30px; width: 80px; font-family: 黑体; color:white;background-color: rgba(0,0,1,0.3);border:none">
			</p>
		</center>
	</form>
</body>
</html>

总的检索页

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>自定义多关键词查询</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>
<body background="D:\java\javaee-workspace\test\background2.jpg"style=" background-repeat:no-repeat ;
background-size:100% 100%;
background-attachment: fixed;">
	<center style="font-family: 楷体;color:white;padding-top:250px">
	<form form action="<%=path %>/MultiFieldQueryParserServlet" method="post" style="font-family: 楷体;color:white;">
		自定义关键词多词查询: 
			关键词1:<input type="text" name="txt1" id="txt1"
					style="height: 30px; width: 100px; background-color: rgba(0,0,1,0.3);border:none;color:white">
					关键词2:<input type="text" name="txt2" id="txt2"
					style="height: 30px; width: 100px; background-color: rgba(0,0,1,0.3);border:none;color:white">
					关键词3:<input type="text" name="txt3" id="txt3"
					style="height: 30px; width: 100px; background-color: rgba(0,0,1,0.3);border:none;color:white"><br><br>

			<p style="padding-top:200px;">
				<input type="submit" value="搜索"
					style="height: 30px; width: 80px; font-family: 黑体; color:white;background-color: rgba(0,0,1,0.3);border:none">
				<input type="button" onclick="window.location.href='KeywordsQuery.jsp'" value="重置条件"
					style="height: 30px; width: 80px; font-family: 黑体; color:white;background-color: rgba(0,0,1,0.3);border:none">
				<input type="button" onclick="window.location.href='functionList.jsp'" value="返回"
					style="height: 30px; width: 80px; font-family: 黑体; color:white;background-color: rgba(0,0,1,0.3);border:none">
			</p>
				</form>
		</center>
</body>
</html>

自定义关键词检索

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page language="java" import="org.apache.lucene.search.Hits"%>
<%@ page language="java" import="org.apache.lucene.document.Document"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
	String str=request.getParameter("Page");
	int Page = Integer.parseInt(str);
 	String title;
	String view;
	String author;
	String time;
	String link;
	int id;
	String ID;
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>检索结果</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>

<body background="D:\java\javaee-workspace\test\background3.jpg"style=" background-repeat:no-repeat ;
background-size:100% 100%;
background-attachment: fixed;">
<form action="SimpleSearchServlet" method="post">
             	<span style="color: white;">3DM-BBS检索:</span>
				<input type="text" name="txt" id="txt"
					style="height: 30px; width: 500px; background-color: rgba(0,0,1,0.3);border:none;color:white"> <input type="submit"
					value="搜索" style="height: 30px; width: 80px;background-color: rgba(0,0,1,0.3);border:none;color:white">
				<input type="button" onclick="window.location.href='jiansuo.jsp'" value="高级检索"
					style="height: 30px; width: 80px; font-family: 黑体; color:white;background-color: rgba(0,0,1,0.3);border:none">
			</form>
	<ul>
		<%
		    int i=0,j=0,p=0;
			Document doc = null;
			for (;p<=Page;p++) {
				if(p!=Page){
					continue;
				}
				for(j=0;j<5;j++){
				i=5*p+j;
				doc =(Document)session.getAttribute("Doc"+i);
				title = doc.get("title");
				view = doc.get("view");
				author = doc.get("author");
				time = doc.get("time");
				id = Integer.parseInt(doc.get("id"));
				ID=doc.get("id");
		%>
		<%
		%>
		<li>
		<a href="<%=doc.get("link")%>" style="color: white;"><%=title%></a><br />
		<span style="color: white;"><a>作者:<%=author %></a></span><br />
		<span style="color: white;"><a>发布时间:<%=time %></a></span><br />
		<span style="color: white;"><a>浏览量:<%=view %></a></span>
		<form action="CollectionServlet"  method="post" style="margin-top:-45px;margin-left:20">
		<input type="text" value=<%=ID %> name="id"	style="visibility:hidden;">
		<input type="submit" value="收藏" name="收藏"
		style="height: 30px; width: 80px;background-color: rgba(0,0,1,0.3);border:none;color:white">
		</form>
		</li>
		<br />
		<a href="F:\pachong\kuaizhao\<%=id-1 %>.jpg"><img id="infoIcon" style="height:13%; weight:13%;margin-top:-200px;margin-left:1100px; " src="F:\pachong\kuaizhao\<%=id-1 %>.jpg"></a>
		<%
			}
		%>
		<%
		%>
	    <p class="paging" style="font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;bottom:80px;left:650px">
          <a href="page.jsp?Page=<%=Page-1%>" style="font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none ">&lt; 上一页 </a>
          <strong >第<<%=p+1 %>>页</strong>
          <a href="page.jsp?Page=<%=Page+1%>" style="font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none ">下一页 &gt;</a>
        </p>

		<%
			}
		%>
		<center>
		<input type="button" onclick="window.location.href='index.jsp'" value="返回" 
					style="height: 30px; width: 80px; font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;bottom:50px;left:712px">
        </center>
	</ul>
</body>
</html>

分页,通过session实现,也可以通过数据库实现。

<%@ page import="java.sql.*" %>
<%@ page import="org.apache.lucene.search.BooleanQuery"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page language="java" import="org.apache.lucene.search.Hits"%>
<%@ page language="java" import="org.apache.lucene.document.Document"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
 	int Page = 0;
 	int end;
 	String title;
	String view;
	String author;
	String time;
	String link;
	int id;
	String ID;
	Hits hits = (Hits) request.getAttribute("hits");
	BooleanQuery bool = (BooleanQuery)request.getAttribute("bool");
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>Result</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>

<body background="D:\java\javaee-workspace\test\background3.jpg"style=" background-repeat:no-repeat ;
background-size:100% 100%;
background-attachment: fixed;">
<div>
             <form action="SimpleSearchServlet" method="post">
             	<span style="color: white;">3DM-BBS检索:</span>
				<input type="text" name="txt" id="txt"
					style="height: 30px; width: 500px; background-color: rgba(0,0,1,0.3);border:none;color:white"> <input type="submit"
					value="搜索" style="height: 30px; width: 80px;background-color: rgba(0,0,1,0.3);border:none;color:white">
				<input type="button" onclick="window.location.href='jiansuo.jsp'" value="高级检索"
					style="height: 30px; width: 80px; font-family: 黑体; color:white;background-color: rgba(0,0,1,0.3);border:none"></br>
				<!-- <span style="color: white; margin-top:-20px">检索词:<%
 	String word = (String) request.getAttribute("txt");
	session.setAttribute("history",word);
 		out.println(word);
     %></span> -->
			</form>
			 <form action="SortServlet" method="post">
				<span style="color: white;">时间排序:</span><span>
				<select name="time_sort"
				style="width: 70px; font-family: 楷体; font-size: large; font-style: normal; font-weight: 400;color:white;background-color: rgba(0,0,1,0.3);border:none">
				<option value='0' selected=''>无</option>
				<option value='1'>降序</option>
				<option value='2'>升序</option>
			</select> 
			<input type="submit"
					value="结果排序" style="height: 30px; width: 80px;background-color: rgba(0,0,1,0.3);border:none;color:white">
			</form>
		</div>
	<%
		String flag = (String) request.getAttribute("flag");
	%>
	<ul>
		<%

		int I=0;
	    int J=0;
	    int P=0;
		Document Doc= null;
		end = hits.length()/5;
		for(;P< hits.length()/5+1;P++) {
			for(J=0;J<5 && (I<hits.length());J++,I++){
			Doc = hits.doc(I);
			session.setAttribute("Doc"+I, Doc);
			}
		}
			int i=0,j,p=0;
			Document doc= null;
			for (; p < hits.length()/5+2;p++) {
				for(j=0;j<5 && i<hits.length();j++,i++){
				doc = hits.doc(i);
				title = doc.get("title");
				view = doc.get("view");
				author = doc.get("author");
				time = doc.get("time");
				link = doc.get("link");
				id = Integer.parseInt(doc.get("id"));
				ID=doc.get("id");
		%>
		<%
		if(Page!=p)
        {
        	i=i+5;
			continue;
        }
		%>
		<li>
		<a href="<%=link%>" style="color: white;"><%=title%></a><br />
		<span style="color: white;"><a>作者:<%=author %></a></span><br />
		<span style="color: white;"><a>发布时间:<%=time %></a></span><br />
		<span style="color: white;"><a>浏览量:<%=view %></a></span>	
		<form action="CollectionServlet"  method="post" style="margin-top:-45px;margin-left:20">
		<input type="text" value=<%=ID %> name="id"	style="visibility:hidden;">
		<input type="submit" value="收藏" name="收藏"
				    style="height: 30px; width: 80px;background-color: rgba(0,0,1,0.3);border:none;color:white">
		</form>
		</li>
		<br />
		<a href="F:\pachong\kuaizhao\<%=id-1 %>.jpg"><img id="infoIcon" style="height:13%; weight:13%;margin-top:-200px;margin-left:1100px; " src="F:\pachong\kuaizhao\<%=id-1 %>.jpg"></a>
		<%
			}
		%>
		<%
		if(Page!=p)
        {
        	continue;
        }
		%>
		<p class="paging" style="font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;bottom:80px;left:650px">
          <a href="page.jsp?Page=<%=0%>" style="font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none ">&lt; 上一页 </a>
          <strong >第<<%=p+1 %>>页</strong>
          <a href="page.jsp?Page=<%=Page+1%>" style="font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none ">下一页 &gt;</a>
        </p>
		<%
			}
		%>
		<center>
		<input type="button" onclick="window.location.href='index.jsp'" value="返回" 
					style="height: 30px; width: 80px; font-family: 楷体; color:white;background-color: rgba(0,0,1,0.3);border:none;position:fixed;bottom:50px;left:712px">
        </center>
	</ul>
</body>
</html>

查询的结果页

<%@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8″%> <% String path = request.getContextPath(); String basePath = request.getScheme() + “://” + request.getServerName() + “:” + request.getServerPort() + path + “/”; %>

跨度查询
多词跨度查询:
关键词A:
关键词B:
跨度设置:

        <p style="padding-top:200px;">
            <input type="submit" value="搜索"
                style="height: 30px; width: 80px; font-family: 黑体; color:white;background-color: rgba(0,0,1,0.3);border:none">
            <input type="button" onclick="window.location.href='spanQuery.jsp'" value="重置条件"
                style="height: 30px; width: 80px; font-family: 黑体; color:white;background-color: rgba(0,0,1,0.3);border:none">
            <input type="button" onclick="window.location.href='functionList.jsp'" value="返回"
                style="height: 30px; width: 80px; font-family: 黑体; color:white;background-color: rgba(0,0,1,0.3);border:none">
        </p>
            </form>
    </center>

多关键词跨度查询

总的来说,java Lucene搜索引擎的工作机制就是在拥有数据的情况下,创建索引,并调用对应的检索功能即可,需要了解检索功能的参数,例如前缀检索的前缀长度、模糊检索的模糊程度、跨度检索的跨度长度等。以及索引的几种类型,是否分词、是否索引。还有就是结果的分页处理,数量较小时可以像我一样用缓存做分页,当数量大的时候,就需要用数据库作为中间过程了。