lucene8.0实践入门介绍1
首先要先下载lucene的相关jar包:
http://apache.01link.hk/lucene/java/8.0.0/lucene-8.0.0.zip
然后解压,拿出三个jar包:
lucene-queryparser-8.0.0.jar
lucene-core-8.0.0.jar
lucene-analyzers-common-8.0.0.jar
创建一个java工程,然后在根目录下创建lib文件夹,将包拷入,添加到项目中(add as libraries...)
一、存入索引的操作IndexWriter
然后直接在项目中创建以下文件(括号内为文件内容):
docs
hello.txt (素胚勾勒出青花,笔锋浓转淡;瓶身描绘的牡丹一如你初妆)
subdocs
hi.txt(落霞与孤鹜齐飞,秋水共长天一色)
然后进行存入索引动作的测试:
package com.company;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.Directory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
public class Index {
public static void main(String[] args) throws Exception {
index0();
}
private static void index0() throws IOException {
//需要读入的文件目录
Path fileDoc = Paths.get("docs");
//需要存储索引的目录,如果不存在,会主动创建
Path index = Paths.get("index");
//FSDirectory打开索引的目录,FS是文件系统的意思,基于磁盘(还有一种基于内存的)
Directory directory = FSDirectory.open(index);
//分词器,标准的分词器,对英文能很好的分词,对于中文只能一个一个拆开(中文推荐使用IK分词器)
Analyzer analyzer = new StandardAnalyzer();
//写索引的配置类,配置使用的分词器为标准分词器
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
//IndexWriter是lucene的核心类,用于存储索引
IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);
//Files是NIO中操作文件的工具,推荐使用,很好用
//Files.isDirectory(path)用于判断是否为目录,是返回true,否则返回false
if (Files.isDirectory(fileDoc)) {
//Files.walkFileTree是一个递归调用目录的方法
// 两个参数: Path start FileVisitor<? super Path> visitor
//第一个是需要递归的目录,第二个是访问文件的接口(SimpleFileVisitor是其中一个实现类)
Files.walkFileTree(fileDoc, new SimpleFileVisitor<>() {
//重写visitFile的方法,这对于
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
//传入的file是一个文件类型的,attrs是该文件的一些属性
indexDocs(file,indexWriter);
return FileVisitResult.CONTINUE;
}
});
} else {
//存储索引的实践操作
indexDocs(fileDoc, indexWriter);
}
//要关闭IndexWriter
indexWriter.close();
}
private static void indexDocs(Path path, IndexWriter indexWriter) throws IOException {
//将文件以类的方式读入
InputStream inputStream = Files.newInputStream(path);
//存入的文档
Document document = new Document();
//存入文档的属性,第一个是字段名,第二个是内容,第三个是否存储内容
//Field有很多实现类,对于不同类型的字段,有不同的实现类来操作StringField是存储String类型的字段,不进行分词
Field field = new StringField("fileName", path.getFileName().toString(), Field.Store.YES);
//将属性加入文档中
document.add(field);
//TextField存入比较大的文本内容,要进行分词。一个是字段名,一个是Reader
//new BufferedReader(new InputStreamReader(inputStream, Charset.forName("utf-8")))通过utf-8格式,获取带缓存的Reader
document.add(new TextField("content",new BufferedReader(new InputStreamReader(inputStream, Charset.forName("utf-8")))));
//LongPoint用于存储long类型数据,不分词
document.add(new LongPoint("modified",Files.getLastModifiedTime(path).toMillis()));
//在存入索引时,打出操作动作
System.out.println("adding files:"+path);
//添加文档
indexWriter.addDocument(document);
//显示关闭流
inputStream.close();
}
}
执行上述代码,控制台打印:
adding files:docs\hello.txt
adding files:docs\subdocs\hi.txt
然后发现项目根目录增加了一个index目录:有几个文件:
_0.cfe
_0.cfs
_0.si
segments_1
write.lock
这样表明已经存入索引了。
如何查看索引,可以使用api写测试用例读出文件内,这个在下一篇博客给出。
还可以使用luke这个工具进行索引的查看:
下载地址:
https://github.com/DmitryKey/luke
注意,因为这个lucene8.0是最新的,所以luke也要版本比较高的才能查看,有些版本低的好像查看不了
因为我本地装了git,所以我直接通过:
git [email protected]:DmitryKey/luke.git 将项目拉到本地的某个文件夹,进入文件夹,在pom.xml的目录下,在cmd命令行的条件下,使用mvn package进行打包,如果不打包,直接双击luke.bat会报错:
ERROR,unable to access jarfile:.\target\luke-swings-with-deps.jar
打包完后,直接双击luke.bat即可如下图:
看到Browse这个按钮,点击,找到项目index目录,打开即可
打开后:
content内容看到没,但是你看到的text都是被拆成一个一个的,因为标准分词器就是这样的,如果要更好的切割中文,使用IK
分词器就可以了。(使用完后,可以多点点luke这个工具,熟悉下)
使用IK分词器:
要引入一个Jar包:下载链接:如果下载不了,可能要*
然后解压:项目中引入:IKAnalyzer2012FF_u1.jar(添加到项目中)
将代码中:Analyzer analyzer = new StandardAnalyzer() 改成:Analyzer analyzer = new IKAnalyzer();
啦啦啦,可以了,然后在执行一次,一看:
adding files:docs\hello.txt
Exception in thread "main" java.lang.AbstractMethodError: Receiver class org.wltea.analyzer.lucene.IKAnalyzer does not define or inherit an implementation of the resolved method abstract createComponents(Ljava/lang/String;)Lorg/apache/lucene/analysis/Analyzer$TokenStreamComponents; of abstract class org.apache.lucene.analysis.Analyzer.
at org.apache.lucene.analysis.Analyzer.tokenStream(Analyzer.java:163)
。。。。。
什么鬼,头晕,看了下源码,Analyzer 的 createComponents方法从两个参数变成一个参数了,IK分词器的还是两个参数的,所以出现异常了,看来要改源码了,睡觉,明天弄。