`

Lucene03---索引位置的优化(内存和磁盘配合使用)

    博客分类:
  • SEO
阅读更多

 

在前面的http://xdwangiflytek.iteye.com/blog/1391510 文章里我们使用Lucene3.5做了一个Demo,在Demo中我们实现了一个创建索引和搜索的功能。那么我们现在在回过头来看看在上面的Demo中,我们是将索引的位置放在本地磁盘中的,在上面最开始我也说了索引的位置可以是本地磁盘也可以是内存中,那么我们可以想想,如果索引放在内存中会怎么样?简单点来想,肯定是速度快没有IO操作,但是呢?程序一退出后就消失了,对吧,但是我们是不是可以考虑两种存放方式配合起来用呢?达到更好点的效果呢?

首先我们来说说创建的这两种位置的方式:

 

磁盘中:

File indexFile = new File(indexPath);
Directory directory = FSDirectory.open(indexFile);

 

 内存中:

Directory directory = new RAMDirectory();
 

 

我们可以这样考虑,在程序运行的时候索引从内存进行读取,在程序退出的时候,再将索引保存到磁盘,但程序再运行的时候,再将磁盘中的索引放到内存中。这样的话是不是效率上好一点啊!

 

下面我们对昨天的Demo进行一个上面所说的简单优化:

 

FirstLucene02.java:

package com.iflytek.lucene;

import java.io.File;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Filter;
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.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;

/**
 * @author xudongwang 2012-2-3
 * 
 *         Email:xdwangiflytek@gmail.com
 */
public class FirstLucene02 {

	/**
	 * 源文件路径
	 */
	private String filePath01 = "F:\\Workspaces\\workspaceSE\\BlogDemo\\luceneDatasource\\HelloLucene01.txt";

	/**
	 * 索引路径
	 */
	private String indexPath = "F:\\Workspaces\\workspaceSE\\BlogDemo\\luceneIndex";

	/**
	 * 分词器,这里我们使用默认的分词器,标准分析器(好几个,但对中文的支持都不好)
	 */
	private Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
	
	private Directory ramDir = null;
	/**
	 * 搜索
	 * 
	 * @param queryStr
	 *            搜索的关键词
	 * @throws Exception
	 */
	public void search(String queryStr) throws Exception {

		// 1、把要搜索的文本解析为Query对象
		// 指定在哪些字段查询
		String[] fields = { "name", "content" };
		// QueryParser: 是一个解析用户输入的工具,可以通过扫描用户输入的字符串,生成Query对象。
		QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_35,
				fields, analyzer);
		// Query:查询,lucene中支持模糊查询,语义查询,短语查询,组合查询等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些类。
		Query query = queryParser.parse(queryStr);
		// 2、进行查询
		IndexReader indexReader = IndexReader.open(ramDir);
		IndexSearcher indexSearcher = new IndexSearcher(indexReader);
		// Filter 过滤器,我们可以将查出来的结果进行过滤,可以屏蔽掉一些不想给用户看到的内容
		Filter filter = null;
		// 10000表示一次性在数据库中查询多少个文档
		// topDocs 类似集合
		TopDocs topDocs = indexSearcher.search(query, filter, 10000);
		System.out.println("总共有【" + topDocs.totalHits + "】条匹配的结果");// 注意这里的匹配结果是指文档的个数,而不是文档中包含搜索结果的个数
		// 3、打印结果
		for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
			int docSn = scoreDoc.doc;// 文档内部编号
			Document document = indexSearcher.doc(docSn);// 根据文档编号取出相应的文档
			File2Document.printDocumentInfo(document);// 打印出文档信息
		}
	}

	/**
	 * 优化创建索引,将索引存在在内存和磁盘配合使用
	 * 
	 * @throws Exception
	 */
	public void createIndexByYouHua() throws Exception {
		File indexFile = new File(indexPath);
		Directory fsDir = FSDirectory.open(indexFile);

		// 1、启动时,将磁盘中的索引读取到内存中
		ramDir = new RAMDirectory(fsDir);
		IndexWriterConfig ramConf = new IndexWriterConfig(Version.LUCENE_35,
				analyzer);

		// 运行程序时操作内存中的索引
		IndexWriter ramIndexWriter = new IndexWriter(ramDir, ramConf);
		Document document = File2Document.file2Document(filePath01);
		ramIndexWriter.addDocument(document);
		ramIndexWriter.close();

		// 2、退出时将内存中的索引保存到磁盘中
		IndexWriterConfig fsConf = new IndexWriterConfig(Version.LUCENE_35,
				analyzer);
		IndexWriter fsIndexWriter = new IndexWriter(fsDir, fsConf);
		fsIndexWriter.addIndexes(ramDir);// 把另外几个索引库中的所有索引数据合并到当前的索引库中
		fsIndexWriter.close();
	}

	public static void main(String[] args) throws Exception {
		FirstLucene02 lucene = new FirstLucene02();
		lucene.createIndexByYouHua();
		lucene.search("iteye");
	}

}

 

 

运行结果:

总共有【1】条匹配的结果

name -->HelloLucene01.txt

content -->Hello, my name is wang xudong, I in iteye blog address is xdwangiflytek.iteye.com.

 

path -->F:\Workspaces\workspaceSE\BlogDemo\luceneDatasource\HelloLucene01.txt

size -->84

 

 

注意上面,添加的时候,索引文件可能会很多,所以这样就会产生更多的IO操作,影响效率,所以需要对索引文件进行优化,减少文件数量,从而减少IO操作。

在上面的优化创建索引的方法里的倒数第二行添加:

fsIndexWriter.commit();
fsIndexWriter.optimize();//对索引文件进行优化,从而减少IO操作

 

 但是在Lucene3.5中这个方法提示过时了

 看源码提示:

  /** This method has been deprecated, as it is horribly
   *  inefficient and very rarely justified.  Lucene's
   *  multi-segment search performance has improved over
   *  time, and the default TieredMergePolicy now targets
   *  segments with deletions.
   *
   * @deprecated */

 

 

 这里还不知道Lucene3.5中对索引文件进行优化的方法,这里暂时留个问题。(?????)

有哪位知道的可以指点一下。

 

 

谢谢“gao2008ss”ok了,这种方式fsIndexWriter.forceMerge(1);,把上面的fsIndexWriter.optimize();替换为fsIndexWriter.forceMerge(1);

 

 

 

 

 

 

 

3
0
分享到:
评论
2 楼 w156445045 2013-04-29  
请问内存索引,是从硬盘读取索引文件放在内存中嘛?
这个好像本来就是这样的吧,
计算机的数据都是放在内存中的吧?
1 楼 hong114126 2012-06-14  
请教一个问题,如果索引文件达到好几个G,还是放入内存中吗????

相关推荐

    java Lucene初级教程

     将索引写入存储器,存储器可以是内存或磁盘。 2.2读出流程  用户提供搜索关键词,经过analyzer处理。 对处理后的关键词搜索索引找出对应的Document。 用户根据需要从找到的Document中提取需要的Field。

    Lucene全文检索引擎工具包.rar

    非结构化数据:指不定⻓或⽆固定格式的数据,如邮件、word⽂档等磁盘上的⽂件 对于结构化数据的全文搜索很简单,因为数据都是有固定格式的,例如搜索数据库中数据使用SQL语句即可 对于非结构化数据,有以下两种⽅法...

    lucene2.9.1完整DEMO及开发文档

    //把索引文件存储到磁盘目录 //创建一个IndexWriter(存放索引文件的目录,分析器,Field的最大长度) iwriter = new IndexWriter(directory, analyzer,true, IndexWriter.MaxFieldLength.UNLIMITED); //iwriter....

    Lucene 是一个基于 Java 的全文信息检索工具包,

    比如你要对一些 HTML 文档,PDF 文档进行索引的话你就首先需要把 HTML 文档和 PDF 文档转化成文本格式的,然后将转化后的内容交给 Lucene 进行索引,然后把创建好的索引文件保存到磁盘或者内存中,最后根据用户输入...

    经典的lucene实例代码及详细解析以及lucene结构流程介绍

    本文并给出一个经典的lucene全文收索例子代码。该例子功能是从磁盘文档建立索引,搜索该文档中的哪个TXT文件包含所搜索内容。最后再大致介绍Lucene的结构模块,应用流程希望对网友能有帮助。

    Lucene-Luke

    Luke是一种专门为Lucece提供图形化界面查询本地磁盘下索引的工具。由于github上面的下载比较慢,所以本人提供了编译好的。

    SQL2005CLR函数扩展 - 关于山寨索引

    对于文件索引lucene才是权威,这里只是自己实现了一个可以实现简单文件索引的半成品.所谓文件索引就是把sql字符串按字节分词保存到磁盘文件目录结构中用来快速定位

    Eclipse开发分布式商城系统+完整视频代码及文档

    │ │ 深入理解Java内存模型.pdf │ │ │ └─课后资料 │ ├─笔记 │ │ 淘淘商城_day20_课堂笔记.docx │ │ │ └─视频 │ 07-使用Jedis连接集群操作.avi │ 00-今日大纲.avi │ 01-RDB持久化方式.avi │ 02...

    论文研究-面向教育视频资源的垂直搜索引擎设计与实现.pdf

    针对Heritrix与Lucene串行组合方案难以实现信息抓取、分析过程与索引过程同时进行的问题,提出一种紧耦合的流程优化组合方案,使网页抓取、网页内容分析筛选和建立索引同时进行,降低了系统IO开销和磁盘空间的占用率...

    Elasticsearch的性能优化

    Elasticsearch(后文简称ES)的基础是Lucene,所有的索引和文档数据是存储在本地的磁盘中,具体的路径可在ES的配置文件../config/elasticsearch.yml中配置,如下:磁盘涉及到IO的读写速度问题,因此如果条件允许的...

    Lucene全文检索(一)

    Lucene实现全文检索的流程 创建索引 获得文档 原始文档:要基于那些数据来进行搜索,那么这些数据就是原始文档。 搜索引擎:使用爬虫获得原始文档 站内搜索:数据库中的数据。 本地搜索:直接使用io流读取磁盘上的...

    Elasticsearch 技术解析与实战.zip

    前言 第1章 Elasticsearch入门 1 1.1 Elasticsearch是什么 1 1.1.1 Elasticsearch的历史 2 1.1.2 相关产品 3 1.2 全文搜索 3 1.2.1 Lucene介绍 4 1.2.2 Lucene倒排索引 4 1.3 基础知识 6 1.3.1 Elasticsearch术语及...

    文件搜索系统

    基于lucene的一个 文件搜索系统 。将目标目录的 所有文件 提取内容 ,建立索引 ,提供搜索服务 。使用的包:tika,lucene,pdfbox.这是工程文件 ,基本完成 ,不过 我无心 继续完善。需要的人拿去..

    JAVA上百实例源码以及开源项目源代码

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    java开源包1

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包10

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    JAVA上百实例源码以及开源项目

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    java开源包8

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

Global site tag (gtag.js) - Google Analytics