Lucene入门教程(一)
在这里分享一下Lucene的学习,主要参考官网上的一下教程和PDF版的《Lucene In Action》。当然,博客中很多内容都是摘自上面两个地方。
1. 什么是Lucene
Lucene是一个高性能的、可扩展的信息检索工具。你可以把它融入到应用程序中以增加索引和搜索功能。Lucene是一个纯Java实现的成熟、自由、开源的软件项目。
它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎。
官方网站:http://lucene.apache.org/
CSDN下载地址:http://download.csdn.net/detail/jolingogo/6472385
2. 索引和搜索
使用Lucene,需要理解索引和搜索这两个概念。
索引:为了快速搜索大量文本文件,首先必须为文件建立索引,就像为一本书建立目录,然后把文本转换成你能够快速搜索到的格式,
而不是使用那种慢速顺序扫描的处理法。这个转换过程就叫做索引操作(indexing),他的输出就称为索引文件(index)。
可以把索引想象成一种数据结构,这种数据结构允许对存储在其中的单词进行快速随机存取。
搜索:是在一个索引中查找关键字的过程,这个过程的目的是为了找到这些关键字在哪些地方出现过。
搜索的质量通常有查确率(precise)和查全率(recall)来衡量。查全率可以衡量这个搜索系统查找到相关文档的能力,
而查确率则是用来衡量搜索系统过滤非相关文档的能力。
3. 第一个示例
准备工作:
1.新建2个文件夹
Lucene_data 里面,我新建了几个txt文本文件
Lucene_index用来存放索引
2. pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.ygy</groupId><artifactId>lucene</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>lucene</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version><scope>test</scope></dependency><!-- Lucene依赖包 --><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-core</artifactId><version>4.5.1</version></dependency><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-analyzers-icu</artifactId><version>4.5.1</version></dependency><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-queryparser</artifactId><version>4.5.1</version></dependency></dependencies>
</project>
3.1 建立索引
package org.ygy.lucene;import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;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.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
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.apache.lucene.util.Version;/*** 建立索引* * @author yuguiyang* */
public class IndexFiles {// -index F:\Lucene_index -docs F:\Lucene_datapublic static void main(String[] args) {String usage = "java org.apache.lucene.demo.IndexFiles [-index INDEX_PATH] [-docs DOCS_PATH] [-update]\n\nThis indexes the documents in DOCS_PATH, creating a Lucene indexin INDEX_PATH that can be searched with SearchFiles";String indexPath = "index"; // 索引存放的路径String docsPath = null; // 需要给哪些文件建立索引(即资源库的地址)boolean create = true; // 是否新建索引for (int i = 0; i < args.length; i++) {if ("-index".equals(args[i])) {indexPath = args[(i + 1)];i++;} else if ("-docs".equals(args[i])) {docsPath = args[(i + 1)];i++;} else if ("-update".equals(args[i])) {create = false;}}if (docsPath == null) {System.err.println("Usage: " + usage);System.exit(1);}// 验证资源文件地址File docDir = new File(docsPath);if ((!docDir.exists()) || (!docDir.canRead())) {System.out.println("Document directory '" + docDir.getAbsolutePath()+ "' does not exist or is not readable, please check the path");System.exit(1);}// 开始建立索引Date start = new Date();try {System.out.println("Indexing to directory '" + indexPath + "'...");// 根据索引存放地址,创建目录Directory dir = FSDirectory.open(new File(indexPath));// 初始化分析器Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_45);//索引配置IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_45, analyzer);if (create) {iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE);} else {iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);}//初始化索引IndexWriter writer = new IndexWriter(dir, iwc);indexDocs(writer, docDir);//关闭索引writer.close();Date end = new Date();System.out.println(end.getTime() - start.getTime() + " total milliseconds");} catch (IOException e) {System.out.println(" caught a " + e.getClass() + "\n with message: " + e.getMessage());}}//递归的方式,遍历每一个文件static void indexDocs(IndexWriter writer, File file) throws IOException {if (file.canRead())if (file.isDirectory()) {String[] files = file.list();if (files != null)for (int i = 0; i < files.length; i++)indexDocs(writer, new File(file, files[i]));} else {FileInputStream fis;try {fis = new FileInputStream(file);} catch (FileNotFoundException fnfe) {return;}try {Document doc = new Document();Field pathField = new StringField("path", file.getPath(), Field.Store.YES);doc.add(pathField);doc.add(new LongField("modified", file.lastModified(), Field.Store.NO));doc.add(new TextField("contents", new BufferedReader(new InputStreamReader(fis, "UTF-8"))));if (writer.getConfig().getOpenMode() == IndexWriterConfig.OpenMode.CREATE) {System.out.println("adding " + file);writer.addDocument(doc);} else {System.out.println("updating " + file);writer.updateDocument(new Term("path", file.getPath()), doc);}} finally {fis.close();}}}
}
好了,虽然,上面的代码还不是很明白,但是,运行一下先。
运行时,需要指定一些参数:
运行结果:
好了,索引建立成功了,看一下,F:\Lucene_index文件夹
这些文件具体是什么,不太清楚,暂且当做是索引文件吧。
3.2 搜索
package org.ygy.lucene;import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
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.FSDirectory;
import org.apache.lucene.util.Version;public class SearchFiles {public static void main(String[] args) throws Exception {//对参数的一些处理String usage = "Usage:\tjava org.apache.lucene.demo.SearchFiles [-index dir] [-field f] [-repeat n] [-queries file] [-query string] [-raw] [-paging hitsPerPage]\n\nSee http://lucene.apache.org/core/4_1_0/demo/ for details.";if ((args.length > 0) && (("-h".equals(args[0])) || ("-help".equals(args[0])))) {System.out.println(usage);System.exit(0);}String index = "index";String field = "contents";String queries = null;int repeat = 0;boolean raw = false;String queryString = null;int hitsPerPage = 10;for (int i = 0; i < args.length; i++) {if ("-index".equals(args[i])) {index = args[(i + 1)];i++;} else if ("-field".equals(args[i])) {field = args[(i + 1)];i++;} else if ("-queries".equals(args[i])) {queries = args[(i + 1)];i++;} else if ("-query".equals(args[i])) {queryString = args[(i + 1)];i++;} else if ("-repeat".equals(args[i])) {repeat = Integer.parseInt(args[(i + 1)]);i++;} else if ("-raw".equals(args[i])) {raw = true;} else if ("-paging".equals(args[i])) {hitsPerPage = Integer.parseInt(args[(i + 1)]);if (hitsPerPage <= 0) {System.err.println("There must be at least 1 hit per page.");System.exit(1);}i++;}}//读取索引IndexReader reader = DirectoryReader.open(FSDirectory.open(new File(index)));//查询索引IndexSearcher searcher = new IndexSearcher(reader);//分析器Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_45);BufferedReader in = null;if (queries != null)in = new BufferedReader(new InputStreamReader(new FileInputStream(queries), "UTF-8"));else {in = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));}//解析器QueryParser parser = new QueryParser(Version.LUCENE_45, field, analyzer);while (true) {if ((queries == null) && (queryString == null)) {System.out.println("Enter query: ");}String line = queryString != null ? queryString : in.readLine();if ((line == null) || (line.length() == -1)) {break;}line = line.trim();if (line.length() == 0) {break;}Query query = parser.parse(line);System.out.println("Searching for: " + query.toString(field));if (repeat > 0) {Date start = new Date();for (int i = 0; i < repeat; i++) {searcher.search(query, null, 100);}Date end = new Date();System.out.println("Time: " + (end.getTime() - start.getTime()) + "ms");}doPagingSearch(in, searcher, query, hitsPerPage, raw, (queries == null) && (queryString == null));if (queryString != null) {break;}}reader.close();}public static void doPagingSearch(BufferedReader in, IndexSearcher searcher, Query query, int hitsPerPage,boolean raw, boolean interactive) throws IOException {TopDocs results = searcher.search(query, 5 * hitsPerPage);ScoreDoc[] hits = results.scoreDocs;int numTotalHits = results.totalHits;System.out.println(numTotalHits + " total matching documents");int start = 0;int end = Math.min(numTotalHits, hitsPerPage);while (true) {if (end > hits.length) {System.out.println("Only results 1 - " + hits.length + " of " + numTotalHits+ " total matching documents collected.");System.out.println("Collect more (y/n) ?");String line = in.readLine();if ((line.length() == 0) || (line.charAt(0) == 'n')) {break;}hits = searcher.search(query, numTotalHits).scoreDocs;}end = Math.min(hits.length, start + hitsPerPage);for (int i = start; i < end; i++) {if (raw) {System.out.println("doc=" + hits[i].doc + " score=" + hits[i].score);} else {Document doc = searcher.doc(hits[i].doc);String path = doc.get("path");if (path != null) {System.out.println(i + 1 + ". " + path);String title = doc.get("title");if (title != null)System.out.println(" Title: " + doc.get("title"));} else {System.out.println(i + 1 + ". " + "No path for this document");}}}if ((!interactive) || (end == 0)) {break;}if (numTotalHits >= end) {boolean quit = false;while (true) {System.out.print("Press ");if (start - hitsPerPage >= 0) {System.out.print("(p)revious page, ");}if (start + hitsPerPage < numTotalHits) {System.out.print("(n)ext page, ");}System.out.println("(q)uit or enter number to jump to a page.");String line = in.readLine();if ((line.length() == 0) || (line.charAt(0) == 'q')) {quit = true;break;}if (line.charAt(0) == 'p') {start = Math.max(0, start - hitsPerPage);break;}if (line.charAt(0) == 'n') {if (start + hitsPerPage >= numTotalHits)break;start += hitsPerPage;break;}int page = Integer.parseInt(line);if ((page - 1) * hitsPerPage < numTotalHits) {start = (page - 1) * hitsPerPage;break;}System.out.println("No such page");}if (quit)break;end = Math.min(numTotalHits, start + hitsPerPage);}}}
}
哎,到目前为止,对上面的程序还不是很理解,但是可以跑通了,还不错,接着学习一下。
运行后,会提示,让你输入要查找的内容:
好了,目前之理解了这么多,先学一会儿,再接着分享哈。
Lucene入门教程(一)相关推荐
- Lucene入门教程
Lucene教程 1 lucene简介 1.1 什么是lucene Lucene是一个全文搜索框架,而不是应用产品.因此它并不像www.baidu.com 或者google Desktop那么 ...
- 全文检索工具Lucene入门教程
目录 1.什么是Lucene 1.1什么是全文检索 1.2 全文检索的应用场景 1.3. 如何实现全文检索 2.Lucene实现全文检索的流程 2.1. 创建索引和搜索流程图 2.2. 创建索引 2. ...
- Lucene入门教程及java实现
一.前言 Lucene 是 apache 软件基金会的一个子项目,由 Doug Cutting 开发,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的库,提 ...
- Lucene 入门教程
了解搜索技术 什么是搜索 简单的说,搜索就是搜寻.查找,在IT行业中就是指用户输入关键字,通过相应的算法,查询并返回用户所需要的信息. 普通的数据库搜索 类似:select * from 表名 whe ...
- Lucene6入门教程(一)简介和学习流程
工作中需要用到Lucene6这个全文检索工具,为项目的开发打下基础.花了比较多的时间熟悉了Lucene,原理,一些网上的案例,以及基本的API使用等,在这里给大家分享一下我关于Lucene6.4.1的 ...
- Apache Solr入门教程
转自:http://blog.csdn.net/u011936655/article/details/51960005 Apache Solr入门教程(初学者之旅) 写在前面:本文涉及solr入门的各 ...
- Logstash:Logstash 入门教程 (一)
Logstash 是一个功能强大的工具,可与各种部署集成. 它提供了大量插件,可帮助你解析,丰富,转换和缓冲来自各种来源的数据. 如果你的数据需要 Beats 中没有的其他处理,则需要将 Logsta ...
- Beats:Beats 入门教程 (一)
在今天的这个教程里,我们来针对初学者如何快速地了解 Beats 是什么,并如何快速地部署 Beats.如果你想了解更多关于 Beats 方面的知识,可以参阅我的文章. 在我们开始 Beats 知识的讲 ...
- Kafka入门教程与详解
1 Kafka入门教程 1.1 消息队列(Message Queue) Message Queue消息传送系统提供传送服务.消息传送依赖于大量支持组件,这些组件负责处理连接服务.消息的路由和传送.持久 ...
最新文章
- video标签poster属性在安卓微信中不生效问题解决
- MATLAB-循环类型相关(for while break continue)
- 【杂谈】您想要的docker环境来了!
- ITK:将图像从一种类型投射到另一种类型,但限制在输出值范围内
- day8网络编程,面向对象1
- uva 10127——ones
- 【kafka】kafka 如何开启 kafka.consumer的监控指标项
- python 图像处理_Python常用库-Pillow图像处理
- gradle 编译失败,出现 permgen space的问题
- 下载文件扩展名php,[宜配屋]听图阁
- Laplacian of Gaussian (LOG) 高斯拉普拉斯算子
- ubuntu开机自动关闭独显,使用集成显卡
- C# 编程指南-事件
- java 开发ocx控件_Java调用ocx控件以及dll
- 计算机学院公众号头像制作,公众号头像需要原创吗?公众号头像怎么制作?
- java POI Excel插入图片
- 装修店铺营销活动策划?
- 爆笑囧人囧事 2009 大合集!
- 远程公司电脑 教你快捷远程公司电脑 公司电脑如何被远程
- 出队列c语言程序,队列的c语言实现