智能提示框主要使用js語句實現,建議先學習jquery和ajax等js,不然不利於理解本文,可是就算什麼都不會依然能夠用本文程序(附帶源碼,不須要任何修改)javascript
對lucene不熟悉的能夠查看個人另外一篇文章《lucene全文檢索學習記錄》http://my.oschina.net/u/1433614/blog/189885 。css
本文工程源碼http://download.csdn.net/detail/leilovegege/6804937 html
Test.html頁面代碼java
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">jquery
<html>web
<head>ajax
<title>google.html</title>apache
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">app
<meta http-equiv="description" content="this is my page">webapp
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
var line = 0;
function del(){
if($("#newDiv")){
$("#newDiv").remove();
line = 0;
}
}
$(document).ready(function(){
//文本框失去焦點時層消失
$(document.body).click(function(){
del();
});
$(document).keydown(function(){
// 38 上 40下 13 回車
if($("#newDiv")){
if(event.keyCode == 40){
$("table tbody tr").eq(line)
.css("backgroundColor", "blue")
.css("color", "white");
$("table tbody tr").eq(line < 0 ? 0 : line - 1)
.css("backgroundColor", "white")
.css("color", "black");
line = (line == $("table tbody tr").length ? 0 : line + 1);
}else if(event.keyCode == 38){
line = (line == 0 ? $("table tbody tr").length : line - 1);
$("table tbody tr").eq(line)
.css("backgroundColor", "blue")
.css("color", "white");
$("table tbody tr").eq(line > $("table tbody tr").length ? 0 : line + 1)
.css("backgroundColor", "white")
.css("color", "black");
}else if(event.keyCode == 13){
$("#key").val($("table tbody tr").eq(line - 1).find("td").eq(0).html());
del();
}
}
});
$("#key").bind("propertychange", function(){
del();
var top = $("#key").offset().top;
var left = $("#key").offset().left;
var newDiv = $("<div/>").width($("#key").width() + 6)
.css("position", "absolute")
.css("backgroundColor", "white")
.css("left", left)
.css("top", top + $("#key").height() + 6)
.css("border", "1px solid blue")
.attr("id", "newDiv");
var table = $("<table width='100%'/>")
.attr("cellpadding", "0")
.attr("cellspacing", "0");
$.post("jqueryServlet", {key: $("#key").val()}, function(xml){
$(xml).find("results result").each(function(){
var key = $(this).attr("key");
var count = $(this).attr("count");
var tr = $("<tr/>").css("cursor", "pointer").mouseout(function(){
$(this).css("backgroundColor", "white").css("color", "black");
}).mouseover(function(){
$(this).css("backgroundColor", "blue").css("color", "white");
}).click(function(){
$("#key").val($(this).find("td").eq(0).html());
del();
});
var td1 = $("<td/>").html(key).css("fontSize", "12px")
.css("margin", "5 5 5 5");
var td2 = $("<td/>").html("共有" + count + "個結果")
.attr("align", "right").css("fontSize", "12px")
.css("color", "green").css("margin", "5 5 5 5");
tr.append(td1).append(td2);
table.append(tr);
newDiv.append(table);
});
});
$(document.body).append(newDiv);
if($("#key").val() == ""){
$("#newDiv").remove();
}
});
});
</script>
</head>
<body>
<h1>搜索</h1>
<div style="margin-top: 20px; margin-left: 30px">
請輸入搜索關鍵字:<input name="key" id="key" style="width: 300">
<input type="button" value="搜一下">
</div>
</body>
</html>
在工程web.xml中添加以下代碼,配置一個servlet
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>jqueryServlet</servlet-name>
<servlet-class>com.test.jqueryServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jqueryServlet</servlet-name>
<url-pattern>/jqueryServlet</url-pattern>
</servlet-mapping>
還有兩個java類
package com.test;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class jqueryServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/xml;charset=utf-8");
request.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
String key = request.getParameter("key");
List<String> list=null;
if(key!=null&&!key.equals("")){
try {
lucene.create();
list=lucene.search(key);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(key+"----------->");
if(list!=null&&!list.equals("null")){
StringBuilder xml = new StringBuilder();
xml.append("<results>");
for(int i=0;i<list.size();i++){
xml.append("<result key='"+list.get(i)+"' count='"+(list.size()-1)+"' ></result>");
}
xml.append("</results>");
out.print(xml.toString());
}
out.flush();
out.close();
}
}
package com.test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
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.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
public class lucene{
static String SourceFileStr = "../webapps/search/source" ; //索引源路徑
static List<Document> list=null; //Document爲後面使用準備的,必定是靜態的
//建立索引
public static void create() throws Exception {
File indexDir = new File( "./index/test1" );//索引文件及存放的路徑
Directory dir=FSDirectory.open(indexDir); //存儲方式,FS爲磁盤,RAM爲內存
Analyzer lucenAnalyzer=new StandardAnalyzer(Version.LUCENE_31); //分詞器
IndexWriterConfig iwc=new IndexWriterConfig(Version.LUCENE_31,lucenAnalyzer);
iwc.setOpenMode(OpenMode.CREATE); //點明是建立新的,原有的索引會被覆蓋
IndexWriter indexWriter=new IndexWriter(dir,iwc);
list=new ArrayList<Document>();
add(SourceFileStr);//調用add()函數,獲取Document
for (int i = 0; i < list.size(); i++) {
indexWriter.addDocument(list.get(i));//將Document寫入索引
}
indexWriter.close();//關閉流
}
//從原文件獲取信息,保存到Document中(實現遍歷目錄下全部文件及子文件夾)
public static void add(String str) throws Exception{
File file = new File( str );
File[] files=file.listFiles();//獲取目錄下的全部文件及文件夾
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()){//若是是文件,將文件信息讀取出來保存到Document中
String temp=FileReaderAll(files[i].getCanonicalPath(),"GBK");//utf-8
System.out.println(temp);
Field FieldPath=new Field("path",files[i].getPath(),Field.Store.YES,Field.Index.NO);
Field FieldBody=new Field("body",temp,Field.Store.YES,Field.Index.ANALYZED,Field.TermVector.WITH_POSITIONS_OFFSETS);
Document document=new Document();
document.add(FieldPath);
document.add(FieldBody);
list.add(document);
}else{//若是是文件夾,遞歸調用本函數
// add(files[i].getPath());
}
}
}
//讀取文件的信息
public static String FileReaderAll(String FileName,String charset)throws IOException{
BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream(FileName),charset));
String line=new String();
String temp=new String();
while ((line=reader.readLine())!=null) {
temp+=line;
}
reader.close();
return temp;
}
//測試創建的索引,實現搜索
public static List<String> search(String str) throws Exception{
List<String> list=new ArrayList<String>();//用於存放搜索結果
String index="./index/test1"; //索引的路徑
IndexReader reader=IndexReader.open(FSDirectory.open(new File(index))); //IndexReader
IndexSearcher searcher=new IndexSearcher(reader); //IndexSearcher
if (searcher!=null) {
Analyzer analyzer=new StandardAnalyzer(Version.LUCENE_31); //分詞器
QueryParser qp=new QueryParser(Version.LUCENE_31,"body",analyzer); //搜索的內容範圍是body(Document)
Query query=qp.parse(str);//搜索關鍵詞
TopDocs results=searcher.search(query, 10);//取前10個搜索結果
ScoreDoc[] hits=results.scoreDocs;
Document document=null;
if (hits.length>0) {
list.add("找到"+hits.length+"條結果");
for (int i = 0; i < hits.length; i++) {
document=searcher.doc(hits[i].doc);
// String body=document.get("body");
String path=document.get("path");
list.add(path);
}
}else
list.add("沒查到結果");
}else{
list.add("沒查找到索引");
}
searcher.close();
reader.close();
return list;
}
}