什么是lucene?
就是一个简单的工具包,java语言特有的,做全文检索用的!
为什么不用数据库的模糊查询?两者都什么区别
1、模糊查询只适用于结构化数据(如数据库中存储的数据);非结构化数据就是文档 图片、音频等等
2、模糊查询速度慢
3、不准确;如果用模糊查询java 会搜索到javascript;
4、会根据相关度来给结果排序;模糊查询是根据字母排序;
5、模糊查询用于小型的软件系统;lucene是用于百度的
怎么用
安装Lucene
Lucene是开发全文检索功能的工具包,从官方网站下载Lucene4.10.3,并解压。
官方网站:http://archive.apache.org/dist/lucene/java/4.10.4/
版本:lucene4.10.3
Jdk要求:1.7以上
现在很多的lucene都是8.0以上的版本,建议不要用那么高的版本,因为当你下载以后,放在项目中会报错,版本太高了!
下载lucene4.10.3版本以后,解压缩
获取以下三个jar包;这三个jar包在不同的位置,怎么找呢?看文件的名字lucene文件夹下面core文件夹里面有lucene-core-4.10.4.jar包
![](https://img-blog.csdnimg.cn/20190515081637694.png)
入门篇
新建一个javaweb项目,把这三个jar包放在Lib文件夹里面;
然后,先开始一个入门级别的项目
1、在d盘新建两个文件夹 img、index;
2、img是放要检索的文件的,这个文件夹里面可以放多个.txt文本做测试,文本里面写不同的内容
3、index文件夹是放索引的位置,这个由代码生成;不用我们管
4、这个代码的流程是这样的
4.1 、给出要检索文件的路径Im和索引要存放的路径index
4.2、然后先创建索引,在执行查询功能
demo来袭
package cn.com.lucene;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
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.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;
import org.apache.lucene.util.Version;
public class Hello {
private static final String PATH_OF_FILE = "D:/img/"; // 待索引文件的目录
private static final String PATH_OF_INDEX = "D:/index/"; // 存放索引文件的目录2
/**
* 测试时,要在D:/img/文件夹中准备几个包含内容的文件(比如txt格式的)
* 然后先执行createIndex()方法,再执行searchFile()方法,最后观看控制台输出即可
*/
public static void main(String[] args) {
Hello h = new Hello();
h.createIndex();
h.searchFile();
}
private void createIndex() {
Directory directory = null;//指定索引被保存的位置
IndexWriter writer = null;//通过IndexWriter写索引
Document doc = null;//我们索引的有可能是一段文本or数据库中的一张表
try {
// 这里是在硬盘上"D:/index/"文件夹中创建索引
directory = FSDirectory.open(new File(PATH_OF_INDEX));
// 这里通过IndexWriterConfig()构造方法的Version.LUCENE_41参数值指明索引所匹配的版本号,并使用了Lucene的标准分词器
writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_41, new StandardAnalyzer(Version.LUCENE_41)));
for (File file : new File(PATH_OF_FILE).listFiles()) {
doc = new Document();
doc.add(new Field("content", new FileReader(file)));
doc.add(new Field("fileName", file.getName(), Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.add(new Field("filePath", file.getAbsolutePath(), Field.Store.YES, Field.Index.NOT_ANALYZED));
writer.addDocument(doc);
}
}
catch (Exception e) {
System.out.println("创建索引的过程中遇到异常,堆栈轨迹如下");
e.printStackTrace();
}
finally {
if (null != writer) {
try {
writer.close(); // IndexWriter在用完之后一定要关闭
}
catch (IOException ce) {
System.out.println("关闭IndexWriter时遇到异常,堆栈轨迹如下");
ce.printStackTrace();
}
}
}
}
private String getContentFromFile(File myFile) {
StringBuffer sb = new StringBuffer();
if (!myFile.exists()) {
return "";
}
try {
BufferedReader in = new BufferedReader(new FileReader(myFile));
String str;
while ((str = in.readLine()) != null) {
sb.append(str);
}
in.close();
}
catch (IOException e) {
e.getStackTrace();
}
return sb.toString();
}
/**
* 搜索文件
*
* @see 1、创建Directory
* @see 2、创建IndexReader
* @see 3、根据IndexReader创建IndexSearcher
* @see 4、创建搜索的Query
* @see 5、根据searcher搜索并返回TopDocs
* @see 6、根据TopDocs获取ScoreDoc对象
* @see 7、根据searcher和ScoreDoc对象获取具体的Document对象
* @see 8、根据Document对象获取需要的值
* @see 9、关闭IndexReader
*/
@SuppressWarnings("deprecation")
private void searchFile() {
IndexReader reader = null;
try {
reader = IndexReader.open(FSDirectory.open(new File(PATH_OF_INDEX)));
IndexSearcher searcher = new IndexSearcher(reader);
// 创建基于Parser搜索的Query,创建时需指定其"搜索的版本,默认搜索的域,分词器"....这里的域指的是创建索引时Field的名字
QueryParser parser = new QueryParser(Version.LUCENE_41, "content", new StandardAnalyzer(Version.LUCENE_41));
Query query = parser.parse("日本"); // 指定==>搜索域为content(即上一行代码指定的"content")中包含"java"的文档
TopDocs tds = searcher.search(query, 10); // 第二个参数指定搜索后显示的条数,若查到5条则显示为5条,查到15条则只显示10条
ScoreDoc[] sds = tds.scoreDocs; // TopDocs中存放的并不是我们的文档,而是文档的ScoreDoc对象
for (ScoreDoc sd : sds) { // ScoreDoc对象相当于每个文档的ID号,我们就可以通过ScoreDoc来遍历文档
Document doc = searcher.doc(sd.doc); // sd.doc得到的是文档的序号
System.out.println(doc.get("fileName") + "[" + doc.get("filePath") + "]"); // 输出该文档所存储的信息
}
}
catch (Exception e) {
System.out.println("搜索文件的过程中遇到异常,堆栈轨迹如下");
e.printStackTrace();
}
finally {
if (null != reader) {
try {
reader.close();
}
catch (IOException e) {
System.out.println("关闭IndexReader时遇到异常,堆栈轨迹如下");
e.printStackTrace();
}
}
}
}
}
解释代码专区
![](https://img-blog.csdnimg.cn/20190515082508512.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTkxNjM3,size_16,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20190515082557876.png)