上一篇文章我们简单介绍了下Lucene的基本情况,作者也是自学的,如果有什么不对的地方还请各位师兄提出来,谢谢
1.将上次文章列出的jar包导入工程
2.整个过程的思路大概就是:
1.将需要被搜索的对象转换成索引对象
2.写入文件夹
3.获取搜索关键词
4.读取索引文件并进行搜索
5.获得结果
3.我们完成第一步,创建索引文件
1.code:
private static final String path = "C:/test/Index";//索引文件放置的地方
private static File file; //索引文件对象
private static Directory directory; //索引放置目录
private static IndexSearcher search;//索引搜索对象
private static final Analyzer analyzer = new StandardAnalyzer();
//这是分词器,我现在用的是标准分词器,采用的一元分词法,下篇文章我会是用结果高亮和中文分词器
public void createIndex(List<String> res) throws IOException{ //创建索引
IndexWriterConfig iwc = new IndexWriterConfig(analyzer);
//创建一个索引写入流配置,并将分词器作为参数传给构造方法
file = new File(path);//创建文件对象
directory = FSDirectory.open(file.toPath());//创建索引放置目录
IndexWriter iw = new IndexWriter(directory, iwc);
//创建索引写入流,并将配置和索引目录通过参数传入,负责将内容写入磁盘
Iterator<String> it = res.iterator();//获取list的迭代器
Document doc = null;//创建document,用来存储索引的单位
while(it.hasNext()){
String str = it.next();
doc = new Document();
doc.getFields().add(new TextField("news", str, Field.Store.YES));
//Field.Store.YES在搜索时被搜索,“news”是该索引的域名,这是将该字段加入索引文档
iw.addDocument(doc);
}
if(iw != null){
iw.close();
}
}
2.以上代码就是创建索引文件,之前忘了介绍Lucene的基本原理,稍后我会补上一篇文章。
3.Lucene将搜索内容转换成文件存储在硬盘上,而每次搜索都是搜索这些文件,并且从这些读取内容,这就意味着即使数据库里更新了,这些文件也无法更新,而且,更新的时候必须把这个文件夹进行手动删除,然后生成新的索引文件
4.这个方法的参数是一个list,这是我从数据库里面拿出来的一个字段,可以根据你的需要更改
4.完成写入后该是是用索引文件了
1.code:
public void search(String keyword) throws Exception{ //关键词搜索
if(directory == null){
new Exception("No Index");
}
IndexReader ir = DirectoryReader.open(directory);//通过索引目录对象打开索引文件读取流
search = new IndexSearcher(ir);//将流给索引对象
QueryParser queryParser = new QueryParser("news", analyzer);
//创建查询解析器,将域名和分词器作为参数
Query query = queryParser.parse(keyword);//将关键词传入解析器获得查询对象
TopDocs topdocs = search.search(query, 100);
//获得前100条结果,topdocs类似于指针容器,指向这些结果
ScoreDoc[] scoredoc = topdocs.scoreDocs;
//获得这些结果的文档集合,文档包括了文档ID和文档得分
for (ScoreDoc scoreDoc2 : scoredoc) {
Document doc = search.doc(scoreDoc2.doc);//根据ID从搜索中搜索出文档
System.out.println(doc.get("news"));//获取文档内容并打印
}
}
}
5.以上就完成了搜索的代码,这是简单的是用
6.所有代码:
1.HelloLucene.java
package lucenetest;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
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.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.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;
public class HelloLucene {
//第一个Lucene程序,是用数据库里的数据
private static final String path = "C:/test/Index";//索引文件放置的地方
private static File file; //索引文件对象
private static Directory directory; //索引放置目录
private static IndexSearcher search;//索引搜索对象
private static final Analyzer analyzer = new StandardAnalyzer();
public void createIndex(List<String> res) throws IOException{ //创建索引
IndexWriterConfig iwc = new IndexWriterConfig(analyzer);//创建一个索引写入流配置,并将分词器作为参数传给构造方法
file = new File(path);//创建文件对象
directory = FSDirectory.open(file.toPath());//创建索引放置目录
IndexWriter iw = new IndexWriter(directory, iwc);//创建索引写入流,并将配置和索引目录通过参数传入
Iterator<String> it = res.iterator();//获取list的迭代器
Document doc = null;//创建document,用来存储索引的单位
while(it.hasNext()){
String str = it.next();
doc = new Document();
doc.getFields().add(new TextField("news", str, Field.Store.YES));//Field.Store.YES在搜索时被搜索,“news”是该索引的域名
iw.addDocument(doc);
}
if(iw != null){
iw.close();
}
}
public void search(String keyword) throws Exception{ //关键词搜索
if(directory == null){
new Exception("No Index");
}
IndexReader ir = DirectoryReader.open(directory);
search = new IndexSearcher(ir);
QueryParser queryParser = new QueryParser("news", analyzer);//创建查询解析器,将域名和分词器作为参数
Query query = queryParser.parse(keyword); //将关键词传入解析器获得查询对象
TopDocs topdocs = search.search(query, 100); //获得前100条结果,topdocs类似于指针容器,指向这些结果
ScoreDoc[] scoredoc = topdocs.scoreDocs;//获得这些结果的文档集合,文档包括了文档ID和文档得分
for (ScoreDoc scoreDoc2 : scoredoc) {
Document doc = search.doc(scoreDoc2.doc);//根据ID从搜索中搜索出文档
System.out.println(doc.get("news"));//获取文档内容并打印
}
}
}
2.Test.java
package lucenetest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import org.newsky.util.JDBCUtil;
public class Test {
public static void main(String[] args) {
HelloLucene h = new HelloLucene();
try {
Connection conn = JDBCUtil.getConn();
PreparedStatement pre = conn.prepareStatement("select newsmodel from tb_news");
ResultSet res = pre.executeQuery();
List<String> list = new ArrayList<String>();
while(res.next()){
list.add(res.getString(1));
}
JDBCUtil.closeAll(conn, pre, res);
h.createIndex(list);
h.search("长京东公司");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
请忽略测试代码的不规范