在这里分享一下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入门教程(一)相关推荐

  1. Lucene入门教程

    Lucene教程 1 lucene简介 1.1 什么是lucene     Lucene是一个全文搜索框架,而不是应用产品.因此它并不像www.baidu.com 或者google Desktop那么 ...

  2. 全文检索工具Lucene入门教程

    目录 1.什么是Lucene 1.1什么是全文检索 1.2 全文检索的应用场景 1.3. 如何实现全文检索 2.Lucene实现全文检索的流程 2.1. 创建索引和搜索流程图 2.2. 创建索引 2. ...

  3. Lucene入门教程及java实现

    一.前言 Lucene 是 apache 软件基金会的一个子项目,由 Doug Cutting 开发,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的库,提 ...

  4. Lucene 入门教程

    了解搜索技术 什么是搜索 简单的说,搜索就是搜寻.查找,在IT行业中就是指用户输入关键字,通过相应的算法,查询并返回用户所需要的信息. 普通的数据库搜索 类似:select * from 表名 whe ...

  5. Lucene6入门教程(一)简介和学习流程

    工作中需要用到Lucene6这个全文检索工具,为项目的开发打下基础.花了比较多的时间熟悉了Lucene,原理,一些网上的案例,以及基本的API使用等,在这里给大家分享一下我关于Lucene6.4.1的 ...

  6. Apache Solr入门教程

    转自:http://blog.csdn.net/u011936655/article/details/51960005 Apache Solr入门教程(初学者之旅) 写在前面:本文涉及solr入门的各 ...

  7. Logstash:Logstash 入门教程 (一)

    Logstash 是一个功能强大的工具,可与各种部署集成. 它提供了大量插件,可帮助你解析,丰富,转换和缓冲来自各种来源的数据. 如果你的数据需要 Beats 中没有的其他处理,则需要将 Logsta ...

  8. Beats:Beats 入门教程 (一)

    在今天的这个教程里,我们来针对初学者如何快速地了解 Beats 是什么,并如何快速地部署 Beats.如果你想了解更多关于 Beats 方面的知识,可以参阅我的文章. 在我们开始 Beats 知识的讲 ...

  9. Kafka入门教程与详解

    1 Kafka入门教程 1.1 消息队列(Message Queue) Message Queue消息传送系统提供传送服务.消息传送依赖于大量支持组件,这些组件负责处理连接服务.消息的路由和传送.持久 ...

最新文章

  1. video标签poster属性在安卓微信中不生效问题解决
  2. MATLAB-循环类型相关(for while break continue)
  3. 【杂谈】您想要的docker环境来了!
  4. ITK:将图像从一种类型投射到另一种类型,但限制在输出值范围内
  5. day8网络编程,面向对象1
  6. uva 10127——ones
  7. 【kafka】kafka 如何开启 kafka.consumer的监控指标项
  8. python 图像处理_Python常用库-Pillow图像处理
  9. gradle 编译失败,出现 permgen space的问题
  10. 下载文件扩展名php,[宜配屋]听图阁
  11. Laplacian of Gaussian (LOG) 高斯拉普拉斯算子
  12. ubuntu开机自动关闭独显,使用集成显卡
  13. C# 编程指南-事件
  14. java 开发ocx控件_Java调用ocx控件以及dll
  15. 计算机学院公众号头像制作,公众号头像需要原创吗?公众号头像怎么制作?
  16. java POI Excel插入图片
  17. 装修店铺营销活动策划?
  18. 爆笑囧人囧事 2009 大合集!
  19. 远程公司电脑 教你快捷远程公司电脑 公司电脑如何被远程
  20. 出队列c语言程序,队列的c语言实现

热门文章

  1. Linux GCC简明教程(使用GCC编写C语言程序)
  2. 我的世界服务端开服基础大全
  3. 将用户名从中文改为英文
  4. 人品计算器代码Android,Android 人品计算器案例
  5. 虚拟机Ubuntu安装开发环境配置
  6. 群晖 NAS 与 APC UPS 的金风玉露
  7. JS逆向03之牛刀开刃,图文并茂,逆入门学习天翼云登录。
  8. javascript高级算法题
  9. 数字图像处理个人练习02--点运算、空域平滑、空域锐化
  10. ORA-01849 :小时值必须介于1和12之间!