Lucene03---索引位置的优化(内存和磁盘配合使用)
来源:互联网 发布:面向对象编程的语言 编辑:程序博客网 时间:2024/06/16 18:45
在前面的http://xdwangiflytek.iteye.com/blog/1391510 文章里我们使用Lucene3.5做了一个Demo,在Demo中我们实现了一个创建索引和搜索的功能。那么我们现在在回过头来看看在上面的Demo中,我们是将索引的位置放在本地磁盘中的,在上面最开始我也说了索引的位置可以是本地磁盘也可以是内存中,那么我们可以想想,如果索引放在内存中会怎么样?简单点来想,肯定是速度快没有IO操作,但是呢?程序一退出后就消失了,对吧,但是我们是不是可以考虑两种存放方式配合起来用呢?达到更好点的效果呢?
首先我们来说说创建的这两种位置的方式:
磁盘中:
![复制代码](/images/icon_copy.gif)
![收藏代码](/images/icon_star.png)
![](/images/spinner.gif)
- File indexFile = new File(indexPath);
- Directory directory = FSDirectory.open(indexFile);
File indexFile = new File(indexPath);Directory directory = FSDirectory.open(indexFile);
内存中:
![复制代码](/images/icon_copy.gif)
![收藏代码](/images/icon_star.png)
![](/images/spinner.gif)
- Directory directory = new RAMDirectory();
Directory directory = new RAMDirectory();
我们可以这样考虑,在程序运行的时候索引从内存进行读取,在程序退出的时候,再将索引保存到磁盘,但程序再运行的时候,再将磁盘中的索引放到内存中。这样的话是不是效率上好一点啊!
下面我们对昨天的Demo进行一个上面所说的简单优化:
FirstLucene02.java:
![复制代码](/images/icon_copy.gif)
![收藏代码](/images/icon_star.png)
![](/images/spinner.gif)
- 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");
- }
- }
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操作。
在上面的优化创建索引的方法里的倒数第二行添加:
![复制代码](/images/icon_copy.gif)
![收藏代码](/images/icon_star.png)
![](/images/spinner.gif)
- fsIndexWriter.commit();
- fsIndexWriter.optimize();//对索引文件进行优化,从而减少IO操作
fsIndexWriter.commit();fsIndexWriter.optimize();//对索引文件进行优化,从而减少IO操作
但是在Lucene3.5中这个方法提示过时了
看源码提示:
![复制代码](/images/icon_copy.gif)
![收藏代码](/images/icon_star.png)
![](/images/spinner.gif)
- /** 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 */
/** 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);
- Lucene03---索引位置的优化(内存和磁盘配合使用)
- Lucene的内存索引和磁盘索引
- 信号量和共享内存的配合使用
- Sybase 索引的使用和优化
- SQL Server索引的使用和优化
- Sybase 索引的使用和优化
- 索引的使用技巧和sql优化
- MongoDB 索引的使用, 管理 和优化
- Mysql索引的设计、使用和优化
- Mysql索引的使用和性能优化
- 内存和磁盘的亲密关系
- 进程与内存7-高速缓存2(目录项高速缓存、索引节点高速缓存和磁盘高速缓存)
- MySQL优化系列(三)--索引的使用、原理和设计优化
- MySQL优化,索引和索引的使用和检测索引是否有效
- Textview的属性lines和padding或layout_margin配合使用来优化界面效果
- linux内存和磁盘使用查询命令
- C/C++快速读写磁盘数据的方法-块读取/异步/优化分析算法/内存文件映射的原理和使用
- C/C++快速读写磁盘数据的方法-块读取/异步/优化分析算法/内存文件映射的原理和使用
- 编写一个截取字符串的函数
- Android非UI线程访问UI线程的方法总结
- javascript 中的 new Date() 的使用总结
- 盛大云计算价格变动及与微软云价格比对(修改)
- [Oracle数据库] 急!关于在AIX4.3.3版本下导8.0.5数据库DMP文件大小的限制!
- Lucene03---索引位置的优化(内存和磁盘配合使用)
- Android多媒体分析(三)通过MediaStore获取Audio信息
- SQL*LOADER操作篇
- android使用google map api 出现INSTALL_FAILED_MISSING_SHARED_LIBRARY 错误
- Lucene04---分词器
- Http 请求
- 全文检索与Lucene学习
- usleep函数
- 发送arp包获取mac