package com.snow.lucene;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.*;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;
import java.io.File;
import java.io.IOException;
public class MainTest {
public static void main(String[] args) {
}
// 写入索引的入门代码
@Test
public void indexWriterTest01() throws Exception {
//1. 创建索引写入器对象
// 参数1: Directory : 指定索引库的目录位置 没有中文和空格
/**
* 常用的实现类:
*
* FSDirectory: 用来指定文件系统的目录, 将索引信息保存到磁盘上
* 优点: 索引可以进行长期保存, 安全系数高
* 缺点: 读取略慢
*
* RAMDriectory: 内存目录, 将索引库信息存放到内存中
* 优点: 读取速度快
* 缺点: 不安全, 无法长期保存, 关机后就消失了
**/
FSDirectory directory = FSDirectory.open(new File("F:\idearWork\test"));
/**
* 默认分词器
*/
//StandardAnalyzer analyzer = new StandardAnalyzer();
/**
* IK 分词器
**/
IKAnalyzer analyzer = new IKAnalyzer();
/**
* 索引写入器的配置类
*/
// 参数2: IndexWriterConfig : 索引写入器的配置对象
// Version.LATEST: 当前导入了那个版本的lucene, 就使用那个版本的, 如果导入了两个版本的就使用最新的
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST,analyzer);
//参数值: APPEND CREATE CREATE_OR_APPEND
/**
* APPEND: 表示追加, 如果索引库存在, 就会向索引库中追加数据, 如果索引库不存在, 直接报错
*
* CREATE: 表示创建, 不管索引库有没有, 每一次都是重新创建一个新的索引库
*
* CREATE_OR_APPEND: 如果索引库有, 就会追加, 如果没有 就会创建索引库
默认值也是 CREATE_OR_APPEND
*/
config.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
IndexWriter indexWriter = new IndexWriter(directory,config);
//2. 添加原始文档数据
Document doc = new Document(); // 刚创建好的文档对象, 没有任何的数据
doc.add(new LongField("id",1L, Field.Store.YES));
doc.add(new TextField("title","2018.1.12传智播客召开年会了", Field.Store.YES));
doc.add(new TextField("content","今年我一定要中大奖, 要来特等奖, 去国外旅游", Field.Store.YES));
indexWriter.addDocument(doc);
//2. 添加原始文档数据
Document doc2 = new Document(); // 刚创建好的文档对象, 没有任何的数据
doc2.add(new LongField("id",2L, Field.Store.YES));
doc2.add(new TextField("title","2019.2.12传智播客召开年会了", Field.Store.YES));
doc2.add(new TextField("content","今年我一定要中大奖, 去全世界旅游", Field.Store.YES));
indexWriter.addDocument(doc2);
//3. 提交文档数据
indexWriter.commit();
//4. 释放资源
indexWriter.close();
}
// 查询索引的入门
@Test
public void indexSearcherTest01() throws Exception{
//1. 创建查询索引器对象
DirectoryReader reader = DirectoryReader.open(FSDirectory.open(new File("F:\idearWork\test")));
IndexSearcher indexSearcher = new IndexSearcher(reader);
//2. 执行查询, 添加查询的条件
// 注意事项:
// QueryParser queryParser = new QueryParser("title",new IKAnalyzer());
// MultiFieldQueryParser queryParser = new MultiFieldQueryParser(new String[]{"年会", "世界"}, new IKAnalyzer());
// Query query = queryParser.parse("大奖");// 其实就是用户号输入的关键词
FuzzyQuery query = new FuzzyQuery(new Term("title","年会"));
// 创建排序对象,需要排序字段SortField,参数:字段的名称、字段的类型、是否反转如果是false,升序。true降序
Sort sort = new Sort(new SortField("id", SortField.Type.LONG, false));
// 搜索数据,查询0~end条
TopDocs topDocs = indexSearcher.search(query, 1,sort); //结果集
System.out.println("本次搜索共" + topDocs.totalHits + "条数据");
// TopDocs topDocs = indexSearcher.search(query, Integer.MAX_VALUE); // 结果集
//3. 获取数据
// TopDocs : 表示的结果集: 一共为分两部分内容 : 一个是总条数 文档的数组
int size = topDocs.totalHits;// 获取总条数
System.out.println("总条数是:"+size);
ScoreDoc[] scoreDocs = topDocs.scoreDocs; // 得分文档的数据
// 高亮的设置 --------------start----------------
SimpleHTMLFormatter formatter =new SimpleHTMLFormatter("<font color='red'>","</font>");
QueryScorer scorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(formatter,scorer);
// 高亮的设置 --------------end----------------
//遍历数组
for (ScoreDoc scoreDoc : scoreDocs) {
// scoreDoc : 得分文档的对象 包含两部分: 一部分是文档的得分, 一部分文档的id值
float score = scoreDoc.score;//文档的得分
int docId = scoreDoc.doc;// 获取文档的id值 从0开始
// 根据id获取文档的原始数据
Document document = indexSearcher.doc(docId);
String id = document.get("id"); // 是手动添加的id字段
String title = document.get("title");
String content = document.get("content");
// 高亮获取 -----------start-------------
title = highlighter.getBestFragment(new IKAnalyzer(), "title", title);
// 高亮获取 -----------end-------------
System.out.println("文档的id为: "+id+";得分是:"+score +"; 文档的标题是:"+title+"; 文档的内容: " + content);
}
}
// 索引修改: 索引的修改本质上就是先删除, 后添加, 所以新修改后的数据,都是在最后面
@Test
public void indexWriterUpdateTest() throws Exception {
//1. 创建indexWriter对象
IndexWriter indexWriter = CreateIndexWrite(new IKAnalyzer());
//2. 添加需要进行修改的文档对象
Document doc = new Document(); // 替换后的数据
doc.add(new StringField("id","5", Field.Store.YES));
doc.add(new TextField("content","这是修改后的数据", Field.Store.YES));
indexWriter.updateDocument(new Term("content","上海"),doc);
//3. 提交
indexWriter.commit();
//4. 释放资源
indexWriter.close();
}
//索引删除:
@Test
public void deleteIndexTest() throws Exception {
//1. 创建 indexWriter对象
IndexWriter indexWriter = CreateIndexWrite(new IKAnalyzer());
//2. 删除索引操作
indexWriter.deleteAll(); //删除全部数据
// 想把 id为5的这个文档删除, 能不能
// 注意: 在进行使用id删除的时候, 如果id是LongFiled此时不能直接使用id来删除数据
//indexWriter.deleteDocuments(new Term("id","2"));
//3. 提交
indexWriter.commit();
//4. 释放资源
indexWriter.close();
}
/**
* 创建写入IndexWriter
* @return
* @throws IOException
*/
private IndexWriter CreateIndexWrite(Analyzer analyzer) throws IOException {
FSDirectory directory = FSDirectory.open(new File("F:\idearWork\test"));
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
return new IndexWriter(directory,config);
}
}
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.10.2</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queries</artifactId>
<version>4.10.2</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-test-framework</artifactId>
<version>4.10.2</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>4.10.2</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>4.10.2</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId>
<version>4.10.2</version>
</dependency>
<!-- 引入IK分词器 -->
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
</dependency>