Lucene 入门程序

需求

实现一个歌词搜索系统,通过关键字搜索,凡是文件名或文件内容包括关键字的文件都要找出来。

注意:该入门程序只对文本文件(.txt)搜索。

开发环境

Jdk:1.7.0_72

开发工具:eclipse indigo

Lucene包:

lucene-core-4.10.3.jar

lucene-analyzers-common-4.10.3.jar

lucene-queryparser-4.10.3.jar

其它:

commons-io-2.4.jar

junit-4.9.jar

Index索引

3.1 创建数据源目录

创建数据源目录F:\develop\lucene\searchsource ,该目录存放要搜索的原始文件。

3.2 创建索引目录 

创建索引目录 F:\develop\lucene\indexdata,该目录存放创建的索引文件。

3.3 Document和Field

索引的目的是为了搜索,索引前要对搜索的内容创建成Document和Field。

3.4 Document

Document文档是Lucene搜索的单位,最终要将文档中的数据展示给用户,文档中包括多个Field,在设计文档对象时,可以将一个Document对应关系数据库的一条记录,字段对应Field,但是要注意:Document结构属于NOSql(非关系),不同的Document包括不同的Field,建议将相同类型数据的Document保持Field一致,方便管理维护,避免将不同类型Field数据融合在一个Document中。

比如:

文件信息Document,Field包括:文件名称、文件类型、文件大小、文件路径、文件内容等,避免加入非文件信息Field。

3.4.1 Field属性

Field是文档中的域,包括Field名和Field值两部分,一个文档可以包括多个Field,Document只是Field的一个承载体,Field值即为要索引的内容,也是要搜索的内容。

1、 是否分析(tokenized)

是:将Field值分析出语汇单元即作分词处理,将词进行索引

比如:商品名称、商品简介等,这些内容用户要输入关键字搜索,由于搜索的内容格式大、内容多需要分析后将语汇单元索引。

否:不作分词处理

比如:商品id、订单号、身份证号等

2、 是否索引(indexed)

是:将Field分析后的词或整个Field值进行索引,只有索引方可搜索到。

比如:商品名称、商品简介分析后进行索引,订单号、身份证号不用分析但也要索引,这些将来都要作为查询条件。

否:不索引无法搜索到

比如:商品id、文件路径、图片路径等,不用作为查询条件的不用索引。

3、 是否存储(stored)

是:将Field值存储在文档中,存储在文档中的Field才可以从Document中获取

比如:商品名称、订单号,凡是将来要从Document中获取的Field都要存储。

否:不存储Field值,不存储的Field无法通过Document获取

比如:商品简介,内容较大不用存储。如果要向用户展示商品简介可以从系统的关系数据库中获取商品简介。

3.4.2 Field常用类型

下边列出了开发中常用 的Filed类型,注意Field的属性,根据需求选择:

3.5 IndexWriter和Directory

IndexWriter是索引过程的核心组件,通过IndexWriter可以创建新索引、更新索引、删除索引操作。IndexWriter需要通过Directory对索引进行存储操作。

Directory描述了索引的存储位置,底层封装了I/O操作,负责对索引进行存储。它的子类常用的包括FSDirectory(在文件系统存储索引)、RAMDirectory(在内存存储索引)。

3.6 索引程序代码

分析:

确定文档的各各域的属性和类型:

文件名称:不分析、索引、存储,使用StringField方法

文件路径:不分析、不索引、存储,使用StoredField方法

文件大小:分析、索引、存储,使用LongField方法

文件内容:分析,索引,不存储,使用TextField方法

代码如下:

public class IndexTest {// 索引源,即源数据目录private static String searchSource = "F:\\develop\\lucene\\searchsource";// 索引目标地址private static String indexFolder = "F:\\develop\\lucene\\indexdata";@Testpublic void testCreateIndex() {try {//从目录中读取文件内容并创建Document文档List<Document> docs = IndexUtils.file2Document(searchSource);//创建分析器,standardAnalyzer标准分析器Analyzer standardAnalyzer = new StandardAnalyzer();// 指定索引存储目录Directory directory = FSDirectory.open(new File(indexFolder));//创建索引操作配置对象IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_10_3,standardAnalyzer);// 定义索引操作对象indexWriterIndexWriter indexWriter = new IndexWriter(directory,indexWriterConfig);// 遍历目录 下的文件生成的文档,调用indexWriter方法创建索引for (Document document : docs) {indexWriter.addDocument(document);}// 索引操作流关闭indexWriter.close();} catch (IOException e) {e.printStackTrace();}}}

IndexUtils.file2Document()方法定义如下:

// 从文件创建Documentpublic static List<Document> file2Document(String folderPath)throws IOException {List<Document> list = new ArrayList<Document>();File folder = new File(folderPath);if (!folder.isDirectory()) {return null;}// 获取目录 中的所有文件File[] files = folder.listFiles();for (File file : files) {//文件名称String fileName = file.getName();System.out.println(fileName);if (fileName.lastIndexOf(".txt") > 0) {// 文件内容String fileContent = FileUtils.readFileToString(file);//文件路径String filePath = file.getAbsolutePath();//文件大小long fileSize = FileUtils.sizeOf(file);//创建文档Document doc = new Document();//创建各各Field域//文件名Field field_fileName = new StringField("fileName", fileName, Store.YES);//文件内容Field field_fileContent = new TextField("fileContent", fileContent, Store.NO);//文件大小Field field_fileSize = new LongField("fileSize", fileSize, Store.YES);//文件路径Field field_filePath = new StoredField("filePath", filePath, Store.YES);//将各各Field添加到文档中doc.add(field_fileName);doc.add(field_fileContent);doc.add(field_fileSize);doc.add(field_filePath);list.add(doc);}}return list;}

4 Search搜索

4.1 索引结构

Lucene的索引结构为倒排索引,倒排文件或倒排索引是指索引对象是文档或者文档集合中的单词等,用来存储这些单词在一个文档或者一组文档中的存储位置,是对文档或者文档集合的一种最常用的索引机制。

Lucene索引index由若干段(segment)组成,每一段由若干的文档(document)组成,每一个文档由若干的域(field)组成,每一个域由若干的项(term)组成。

项是最小的索引单位,如果Field进行分析,可能会分析出多个语汇单元(词),每个词就是一个Term项,如果Field不进行分析,整个Field就是一个Term项。

项直接代表了一个字符串以及其在文件中的位置、出现次数等信息。域将项和文档进行关联。

4.2 使用Luke查看索引

Luke作为Lucene工具包中的一个工具(http://www.getopt.org/luke/),用于查询、修改lucene的索引文件。

打开Luke方法:

cmd运行:java  -jar lukeall-4.10.3.jar

如果需要加载第三方分词器,如果需要加载第三方分词器,需通过java.ext.dirs加载jar包:

可简单的将第三方分词器和lukeall放在一块儿,cmd下运行:。

java -Djava.ext.dirs=. -jar lukeall-4.10.3.jar

4.3 确定索引目录

搜索是要从索引中查找,确定索引目录即上边创建的索引目录 F:\develop\lucene\indexdata。

4.4 IndexSearcher和IndexReader

通过IndexSearcher执行搜索,构建IndexSearcher需要IndexReader读取索引目录,如下图:

代码如下:

// 指定 目录File folder = new File(indexFolder);Directory directory = FSDirectory.open(folder);// indexReaderIndexReader indexReader = DirectoryReader.open(directory);// 定义indexSearcherIndexSearcher indexSearcher = new IndexSearcher(indexReader);

需要注意:

Indexreader打开需要耗费很大的系统资源,建议使用一个IndexReader,如果索引进行添加、修改或删除需要打开新的Reader才可以搜索到。

IndexSearcher搜索方法如下:

4.5 搜索程序代码

public class SearchTest {// 索引目录地址private static String indexFolder = "F:\\develop\\lucene\\indexdata";//查询方法@Testpublic void testTermQuery() throws IOException {// 创建查询对象,根据文件名称域搜索匹配文件名称的文档Query query = new TermQuery(new Term("fileName", "springmvc_test.txt"));// 指定索引目录Directory directory = FSDirectory.open(new File(indexFolder));// 定义IndexReaderIndexReader reader = DirectoryReader.open(directory);// 创建indexSearcherIndexSearcher indexSearcher = new IndexSearcher(reader);// 执行搜索TopDocs topDocs = indexSearcher.search(query, 100);// 提取搜索结果ScoreDoc[] scoreDocs = topDocs.scoreDocs;System.out.println("共搜索到总记录数:" + topDocs.totalHits);for (ScoreDoc scoreDoc : scoreDocs) {// 文档idint docID = scoreDoc.doc;// 得到文档Document doc = indexSearcher.doc(docID);// 输出 文件内容IndexUtils.printDocumentOfFile(doc);}}

IndexUtils.printDocumentOfFile()方法:

//从文档中读取文件内容public static void printDocumentOfFile(Document doc){System.out.println("------------------------------");System.out.println("文件名称 =" + doc.get("fileName"));System.out.println("文件大小 =" + doc.get("fileSize"));System.out.println("文件内容 =" + doc.get("fileContent"));}

4.6 TopDocs

Lucene搜索结果可通过TopDocs遍历,TopDocs类提供了少量的属性,如下:

注意:

Search方法需要指定匹配记录数量n:indexSearcher.search(query, n)

TopDocs.totalHits:是匹配索引库中所有记录的数量

TopDocs.scoreDocs:匹配相关度高的前边记录数组,scoreDocs的长度小于等于search方法指定的参数n

Lucene教程--入门程序详解相关推荐

  1. Windows编程入门程序详解

    Windows编程入门程序详解 1.     程序 /************************************************************************* ...

  2. lucene教程--全文检索技术详解

    一 什么是全文检索 1.1 全文检索概念 全文检索是一种将文件中所有文本与检索项匹配的检索方法.它可以根据需要获得全文中有关章.节.段.句.词等信息.计算机程序通过扫描文章中的每一个词,对每一个词建立 ...

  3. Lucene教程--Analyzer分析器详解

    Analyzer分析器 1 Analyzer使用时机 1.1 创建索引时使用Analyzer 输入关键字进行搜索,当需要让该关键字与文档域内容所包含的词进行匹配时需要对文档域内容进行分析,需要经过An ...

  4. 图文解说OpenCV开发一 - 环境配置和入门程序详解

    1 我用的是OpenCV 2.4.3版本,当前最新版本已经比这个新了:安装好的目录结构如下图: OpenCV 2.4.3的安装包可以到我网盘下载: http://pan.baidu.com/s/1kT ...

  5. Oracle11g安装教程、配置实例、监听、客户端程序详解_Windows篇

    Oracle11g安装教程.配置实例.监听.客户端程序详解_Windows篇 文章目录 Oracle11g安装教程.配置实例.监听.客户端程序详解_Windows篇 前言 一.数据库的安装前准备,前提 ...

  6. 小程序开发入门超详解之WXML

    小程序开发入门超详解之WXML 小程序入门开发超详解版之WXML 开发框架组成介绍 WXML语法 WXML特性 小程序入门开发超详解版之WXML 欢迎大家添加月神的微信:18333806737进行专业 ...

  7. python 快速排序_小白入门知识详解:Python实现快速排序的方法(含实例代码)...

    前言: 今天为大家带来的内容是:小白入门知识详解:Python实现快速排序的方法(含实例代码)希望通过本文的内容能够对各位有所帮助,喜欢的话记得点赞转发收藏不迷路哦!!! 提示: 这篇文章主要介绍了P ...

  8. h2 不能访问localhost_SpringBoot2.x系列教程44--H2数据库详解及搭建Web控制台

    SpringBoot2.x系列教程44--H2数据库详解及搭建Web控制台 作者:一一哥 我在上一章节中讲解了Spring Boot中整合Mybatis,接下来我给大家介绍一款内存数据库--H2. H ...

  9. mysql 实例复制_MYSQL教程MySQL 复制详解及简单实例

    <MysqL教程MysqL 复制详解及简单实例>要点: 本文介绍了MysqL教程MysqL 复制详解及简单实例,希望对您有用.如果有疑问,可以联系我们. MysqL 复制详解及简单实例 主 ...

最新文章

  1. 对于图像分类任务,相对于全连接的DNN,CNN模型的主要优点有哪些?
  2. 北京清华长庚医院与数据院签约,医工结合促医疗大健康发展
  3. 弹出窗口, 不显示工具栏等。
  4. mysql的innodb表生成的物理文件_MySQL innodb表使用表空间物理文件复制或迁移表
  5. Geek爱旅行 - 穿越时间的旅行
  6. 别说“我已经很努力了”
  7. 2021年下半年网络工程师上午真题及答案解析
  8. 第五十篇、OC中常用的第三插件
  9. cognos报表制作(三)Cube开发
  10. Cisco2811路由器的首次接触
  11. 数字孪生智慧选煤厂:数据监控赋能矿山高效生产
  12. a=a*10+b型题目
  13. firewalld防火墙IP伪装和端口转发
  14. Nginx反向代理的配置
  15. 怎么解决打印机“正在删除-已发送到打印机”打印状态
  16. windows防火墙是干什么的_请教个人防火墙是做什么用的,
  17. 如何检测文章被搜索引擎收录(如何让搜索引擎收录网站)
  18. 芝加哥面孔数据库(CFD)的人脸模板
  19. Sql server语句(增删改查)
  20. sklearn专题四:降维算法

热门文章

  1. 一条语句执行跨越若干个数据库
  2. 算符“.*”和“-*”,用于“成员指针”
  3. MiniGUI细节处理(转)
  4. (chap4 IP协议) CIDR协议
  5. Kubernetes二次开发--Operator的使用
  6. 09-LearnTheArchitecture-MemoryManagement
  7. TEEC_AllocateSharedMemory()和 TEEC_RegisterSharedMemory()的总结
  8. [How TO]-堡垒机快捷登陆SSH服务器-expect自动输密码
  9. php 数据显示格式,php数据格式
  10. WIN32 使用 MUTEX 实现禁止多开