Lucene 全文检索

[b]1,信息检索与数据库的搜索对比 -- DB就不是为全文检索而设计的[/b]
a> 数据库的搜索不能实现我们的全文检索的要求,原因如下: 匹配效果:如搜索 ant,在 sql 中使用 like %ant%'是会搜索出 planting 的,但他不应出现.
b> 查出的结果没有相关度排序,不知道有用的结果在哪一页.
c> 搜索速度太慢,达不到毫秒级的要求

[b]2, 整体流程[/b]
[img]http://dl.iteye.com/upload/attachment/476858/6ab1048a-1920-3157-a2a6-46d453785787.jpg[/img]


[img]http://dl.iteye.com/upload/attachment/476870/080a8328-0ed7-3ef9-b462-86722279bc25.jpg[/img]


[b]3, 主要概念[/b]
索引, 分词器, 高亮器, 过滤器

[b]4, 代码[/b]
package cn.itcast.lucene.helloworld;

import jeasy.analysis.MMAnalyzer;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Filter;
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.junit.Test;

import cn.itcast.lucene.utils.File2DocumentUtils;

public class HelloWorld2 {

String filePath = "luceneDatasource\\ch1.txt";
String filePath2 = "luceneDatasource\\ch2.txt";
String filePath3 = "luceneDatasource\\ch3.txt";
String filePath4 = "luceneDatasource\\ch4.txt";

String indexPath = "luceneIndex2";

Analyzer analyzer = new MMAnalyzer();

/**
* 创建索引
*
* IndexWriter 是用来操作(增、删、改)索引库的
*/
@Test
public void createIndex() throws Exception {
// file --> doc
Document doc = File2DocumentUtils.file2Document(filePath);
Document doc2 = File2DocumentUtils.file2Document(filePath2);
Document doc3 = File2DocumentUtils.file2Document(filePath3);
Document doc4 = File2DocumentUtils.file2Document(filePath4);

// 建立索引
IndexWriter indexWriter = new IndexWriter(indexPath, analyzer, true,
MaxFieldLength.LIMITED);
indexWriter.addDocument(doc);
indexWriter.addDocument(doc2);
indexWriter.addDocument(doc3);
indexWriter.addDocument(doc4);

indexWriter.close();
}

/**
* 搜索
*
* IndexSearcher 是用来在索引库中进行查询的
*/
@Test
public void search() throws Exception {
// String queryString = "document";
String queryString = "商品";

// 1,把要搜索的文本解析为 Query
String[] fields = { "content" };
QueryParser queryParser = new MultiFieldQueryParser(fields, analyzer);
Query query = queryParser.parse(queryString);

// 2,进行查询
IndexSearcher indexSearcher = new IndexSearcher(indexPath);
Filter filter = null;
TopDocs topDocs = indexSearcher.search(query, filter, 10000);
System.out.println("总共有【" + topDocs.totalHits + "】条匹配结果");

// 3,打印结果
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
int docSn = scoreDoc.doc; // 文档内部编号
Document doc = indexSearcher.doc(docSn); // 根据编号取出相应的文档
File2DocumentUtils.printDocumentInfo(doc); // 打印出文档信息
}
}
}

package cn.itcast.lucene.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumberTools;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;

public class File2DocumentUtils {

// 文件:name, content, size, path
public static Document file2Document(String path) {
File file = new File(path);

Document doc = new Document();
doc.add(new Field("name", file.getName(), Store.YES, Index.ANALYZED));
doc.add(new Field("content", readFileContent(file), Store.YES, Index.ANALYZED));
doc.add(new Field("size", NumberTools.longToString(file.length()), Store.YES, Index.NOT_ANALYZED));
doc.add(new Field("path", file.getAbsolutePath(), Store.YES, Index.NOT_ANALYZED));
return doc;
}

// public static void document2File(Document doc ){
//
// }

/**
* 读取文件内容
*/
public static String readFileContent(File file) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
StringBuffer content = new StringBuffer();

for (String line = null; (line = reader.readLine()) != null;) {
content.append(line).append("\n");
}

return content.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

/**
* <pre>
* 获取 name 属性的值的两种方法:
* 1,Field f = doc.getField("name");
* f.stringValue();
* 2,doc.get("name");
* </pre>
*
* @param doc
*/
public static void printDocumentInfo(Document doc) {
// Field f = doc.getField("name");
// f.stringValue();
System.out.println("------------------------------");
System.out.println("name = " + doc.get("name"));
System.out.println("content = " + doc.get("content"));
System.out.println("size = " + NumberTools.stringToLong(doc.get("size")));
System.out.println("path = " + doc.get("path"));
}

}



5, 相关查询文件 & JAR包
见附件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值