步骤一:创建maven现目
步骤二:配置pom.xml文件,代码如下:
<pre name="code" class="java"> <!-- junit包
因为是java程序,,需要用到@Test,这就是他的jar包下载。-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- lucene核心包
以下这三个是用在lucene的全部jar包,core是核心包,queryparser是查询jar包。
查询被索引文件如果是全英文的情况下,pom.xml文件写这三个,就欧了!-->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>5.3.1</version>
</dependency>
<!-- 查询解析器 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>5.3.1</version>
</dependency>
<!-- 分析器 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>5.3.1</version>
</dependency>
<!-- 很明显,这个是查询被检索文件为全中文的情况下,
加上以上的三个,再加上这两个就行了。
值得提一下,“高亮显示”的jar包可加可不加,
在这里面加上,是因为这个在后面会用到。
但是还是建议大家把这个加上,懂得多也不是个错。
-->
<!-- 中文分词查询器smartcn -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-smartcn</artifactId>
<version>5.3.1</version>
</dependency>
<!-- 高亮显示 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId>
<version>5.3.1</version>
</dependency>
步骤三:开始写代码,代码如下:
import java.nio.file.Paths;
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.StringField;
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.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Before;
import org.junit.Test;
/**
* 对被索引的文章进行crud
* @author SZQ
*
*/
public class IndexDocument {
//写测试数据,这些数据是写到索引文档里去的。
private String ids[] = {"1","2","3"}; //标示文档
private String citys[] = {"BeiJing","HeBei","ShanXi"};
private String cityDes[] = {
"BeiJing is the captial of China!",
"HeBei is my hometown!",
"ShanXi is a beautiful city!"
};
private Directory dir;
//每次启动的时候都会执行这个方法,写索引的东西都写在setUp方法里
@Before
public void setUp() throws Exception {
//得到读取索引文件的路径
dir = FSDirectory.open(Paths.get("E:\\luceneDemo2"));
//获取IndexWriter实例
IndexWriter writer = getWriter();
for(int i=0;i<ids.length;i++){
Document doc=new Document();
doc.add(new StringField("id", ids[i], Field.Store.YES));
doc.add(new StringField("city",citys[i],Field.Store.YES));
doc.add(new TextField("desc", cityDes[i], Field.Store.NO));
// 添加文档
writer.addDocument(doc);
}
writer.close();
}
/**
* 获取IndexWriter实例
* @return
* @throws Exception
*/
private IndexWriter getWriter() throws Exception{
//实例化分析器
Analyzer analyzer = new StandardAnalyzer();
//实例化IndexWriterConfig
IndexWriterConfig con = new IndexWriterConfig(analyzer);
//实例化IndexWriter
IndexWriter writer = new IndexWriter(dir, con);
return writer;
}
/**
* 测试写了几个文档(对应图片一)
* @throws Exception
*/
@Test
public void testIndexWriter()throws Exception{
//获取IndexWriter实例
IndexWriter writer=getWriter();
System.out.println("写入了"+writer.numDocs()+"个文档");
//关闭writer
writer.close();
}
}
图片一:出现图一,就说明检索文件成功!
/**
* 测试读取文档(对应图片二)
* @throws Exception
*/
@Test
public void testIndexReader()throws Exception{
//根据路径得到索引读取
IndexReader reader=DirectoryReader.open(dir);
//公共是多少文件,也就是最大文档数
System.out.println("最大文档数:"+reader.maxDoc());
//读取的实际文档数
System.out.println("实际文档数:"+reader.numDocs());
//关闭reader
reader.close();
}
图片二:首先来解释一下是什么是最大文件数:指的是你一共索引了多少的文档,写了7个,就是7个,写了3个就是3个。实际文档数是真正3个被索引的文档。值得注意的是,检索文件之后,手动删除图一当中的所有文件,否则会查出重复的文档数。因为在读取文档数的时候,相当于又重新对文档写了索引。
/**
* 测试删除 在合并前(对应图片三)
* @throws Exception
*/
@Test
public void testDeleteBeforeMerge()throws Exception{
//获取IndexWriter实例
IndexWriter writer=getWriter();
//统计删除前的文档数
System.out.println("删除前:"+writer.numDocs());
//Term:第一个参数是删除的条件,第二个是删除的条件值
writer.deleteDocuments(new Term("id","1"));
//提交writer(如果不提交,就不能删除)
writer.commit();
//显示删除在合并前的最大文档数量
System.out.println("writer.maxDoc():"+writer.maxDoc());
//显示删除在合并前的实际数量
System.out.println("writer.numDocs():"+writer.numDocs());
//关闭writer
writer.close();
}
/**
* 测试删除 在合并后(对应图片四)
* @throws Exception
*/
@Test
public void testDeleteAfterMerge()throws Exception{
//获取IndexWriter实例
IndexWriter writer=getWriter();
//删除前的文档数
System.out.println("删除前:"+writer.numDocs());
//Term:第一个参数是删除的条件,第二个是删除的条件值
writer.deleteDocuments(new Term("id","1"));
// 强制删除
writer.forceMergeDeletes();
//提交writer
writer.commit();
//显示删除在合并后的最大文档数量
System.out.println("writer.maxDoc():"+writer.maxDoc());
//显示删除在合并后的实际数量
System.out.println("writer.numDocs():"+writer.numDocs());
//关闭writer
writer.close();
}
对比下:
/**
* 测试更新(对应图片五)
* @throws Exception
*/
@Test
public void testUpdate()throws Exception{
//获取IndexWriter实例
IndexWriter writer=getWriter();
//实例化文档
Document doc=new Document();
//向文档里添加值
doc.add(new StringField("id", "1", Field.Store.YES));
doc.add(new StringField("city","qingdao",Field.Store.YES));
doc.add(new TextField("desc", "dsss is a city.", Field.Store.NO));
//更新文档
/**
* 第一个参数是根据id为1的更新文档,,
* 第二个是更改的内容
*
* 过程:先把查到的文档删掉,再添加。这就是更新。但是原来的数据还在;
*/
writer.updateDocument(new Term("id","1"), doc);
//关闭writer
writer.close();
}
细心的同学可能已发现,在删除合并之前,删除前为3,最大文档数为 3;而合并后的图片四中删除前仍为3,但是最大文档数为 2.这说明了这两幅图都已删除成功,但是图片三没有真正的把删除文档,但实际文档数是代表已经删除了一个文档。
合并前在luke中显示的效果:
相反,图片四不管是最大文档数还是实际文档数都是2,更能看出已经强制删除了一个文档,合并后在luke中显示的效果:
所以,个人觉得,合并后是比较准确,直观的看出确实是删除了文档。
好了,,这就是对被索引文档的一个CRUD。还有一个工具还没给大家介绍,那就是Luke。那么什么是Luke呢?
复制url:http://www.getopt.org/luke/,说白了就是lucene全文检索的第三方工具,效果如下,
luke使用步骤:
步骤一:解压luke-5.3.0-luke-release.zip;
步骤二:双击luke.bat,出现如下图的效果(左下角的
空白处和右下角的空白处没有东西);
步骤三:点击左上角的FIle,看见Open Lucene Index这
个 选项,点击之后,就会出现你的路径,选
择索引文档所在文件夹的全路径就可以了。
最后的效果就和下图一模一样了。
温馨提示:jDK必须为1.7或1.8以上,否则会用不了。