`
刘小小尘
  • 浏览: 67503 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

lucene使用教程3 --常用类的对象

 
阅读更多

你需要以下类来执行这个简单的索引与搜索的过程:

1、IndexWriter

2、IndexSearcher

3、IndexReader

4、Directory

5、Analyzer

6、Document

7、Field

8、Term

9、Query

10、TermQuery

11、Hits

接下来是对这些类的一个简短的浏览,针对它们在Lucene的角色,给出你粗略的概念。接下来我们开始介绍这些类。

IndexWriter类

IndexWriter是在索引过程中的中心组件。这个类创建一个新的索引并且添加文档到一个已有的索引中。你可以把IndexWriter想象成让你可以对索引进行写操作的对象,但是不能让你读取或搜索。此处使用线程同步的方式确保对象的使用高效、安全和减少内存的压力。

以下代码是从网络上粘贴过来的,代码可能会有错误,但是原理都是一样的,明白原理,什么都简单

MyIndexWriter中对IndexWriter的创建和回收:

public class MyIndexWriter {
	private static Analyzer analyzer = new PaodingAnalyzer();
	private static IndexWriter indexWriter;
	private static ArrayList<Thread> threadList = new ArrayList<Thread>();
	private static Directory dir = null;
	private MyIndexWriter() {
	}
	/**
	 * 
	 * @function 创建indexWriter对象
	 * @param indexFilePath 创建索引的路径
	 * @param create 创建方式
	 * @return
	 */
	public static IndexWriter getInstance(String indexFilePath, boolean create) {
		synchronized (threadList) {
			if (indexWriter == null) {
				File indexFile = new File(indexFilePath);
				File lockfile = new File(indexFilePath + "/write.lock");
				try {
					if (!indexFile.exists()) {
						indexFile.mkdir();
					}

					dir = FSDirectory.open(indexFile);
					if (IndexWriter.isLocked(dir)) {// 判断目录是否已经锁住
						IndexWriter.unlock(dir);
					}
					if (lockfile.exists()) {
						lockfile.delete();
					}
					if (create) {
						indexWriter = new IndexWriter(dir, analyzer, true,
								MaxFieldLength.UNLIMITED);
					} else {
						if (IndexReader.indexExists(dir)) {
							indexWriter = new IndexWriter(dir, analyzer, false,
									MaxFieldLength.UNLIMITED);
						} else {
							indexWriter = new IndexWriter(dir, analyzer, true,
									MaxFieldLength.UNLIMITED);
						}
					}
					indexWriter.setMergeFactor(1000);
					indexWriter.setMaxFieldLength(Integer.MAX_VALUE);

					// 控制写入一个新的segment前在内存中保存的最大的document数目
					indexWriter.setRAMBufferSizeMB(32);
					indexWriter.setMaxMergeDocs(200);

				} catch (CorruptIndexException e) {
					e.printStackTrace();
				} catch (LockObtainFailedException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					indexFile=null;
					lockfile=null;
				}
			}
			if (!threadList.contains(Thread.currentThread()))
				threadList.add(Thread.currentThread());
			return indexWriter;
		}
	}

	/**
	 * 
	 * @function 关闭indexWriter对象
	 */
	public static void close() {
		synchronized (threadList) {
			if (threadList.contains(Thread.currentThread()))
				threadList.remove(Thread.currentThread());

			if (threadList.size() == 0) {
				try {
					if (indexWriter != null) {
						indexWriter.optimize();
						indexWriter.commit();
						indexWriter.close();
						indexWriter = null;
					}
					if (dir != null) {
						dir.close();
					}
				} catch (CorruptIndexException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

使用IndexWriter添加索引

实现过程:把普通对象转换成IndexWriter需要的Documents文档对象,IndexWriter是addDocument()方法把对象索引到文件。

/**
	 * 
	 * @function 创建文档索引
	 * @param list 索引对象集合
	 */
	private static void createDocIndex(List<SearchBean> list,
			String indexFilePath, boolean createMode) {
		try {
			// System.out.println(indexFilePath);
			indexWriter = MyIndexWriter.getInstance(indexFilePath + "/index",
					createMode);
			// 对所有的实体进行索引创建
			for (SearchBean searchBean : list) {
				// 建立一个lucene文档
				doc = new Document();
				// 搜索内容
				String id = searchBean.getId();
				String title = searchBean.getTitle();
				String content = searchBean.getContent();
				String url = searchBean.getUrl();
				String keyword = searchBean.getKeyword();
				String time = searchBean.getTime();
				String author = searchBean.getAuthor();
				String module = searchBean.getModule();
				String type = searchBean.getType();
				// 添加主键至文档,不分词,不高亮。
				doc.add(new Field("id", id, Field.Store.YES,
						Field.Index.NOT_ANALYZED, Field.TermVector.NO));
				// 利用htmlparser得到处方html的纯文本
				Parser parser = new Parser();
				parser.setInputHTML(title);
				String titleText = parser.parse(null).elementAt(0)
						.toPlainTextString().trim();
				// 添加到文档
				doc.add(new Field("title", titleText, Field.Store.YES,
						Field.Index.ANALYZED,
						Field.TermVector.WITH_POSITIONS_OFFSETS));

				parser.setInputHTML(content);
				String contentText = parser.parse(null).elementAt(0)
						.toPlainTextString().trim();
				// 添加到文档
				doc.add(new Field("content", contentText, Field.Store.YES,
						Field.Index.ANALYZED,
						Field.TermVector.WITH_POSITIONS_OFFSETS));

				doc.add(new Field("url", url, Field.Store.YES,
						Field.Index.NOT_ANALYZED, Field.TermVector.NO));

				doc.add(new Field("keyword", keyword, Field.Store.YES,
						Field.Index.ANALYZED,
						Field.TermVector.WITH_POSITIONS_OFFSETS));

				doc.add(new Field("time", time, Field.Store.YES,
						Field.Index.ANALYZED,
						Field.TermVector.WITH_POSITIONS_OFFSETS));
				doc.add(new Field("author", author, Field.Store.YES,
						Field.Index.NOT_ANALYZED, Field.TermVector.NO));
				doc.add(new Field("module", module, Field.Store.YES,
						Field.Index.NOT_ANALYZED, Field.TermVector.NO));
				doc.add(new Field("type", type, Field.Store.YES,
						Field.Index.NOT_ANALYZED, Field.TermVector.NO));
				indexWriter.addDocument(doc);
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		} finally {
			MyIndexWriter.close();
		}
	}

使用IndexWriter删除索引

删除文档是需要保证的是数据的唯一性,一般把不分词的域作为判断的依据,如果一个域还不能完全保证数据的唯一性,那就需要多个域的组合判断。

下文教你使用组合域删除唯一对象,这是Lucene教程里面没有涉及到的内容,目前使用正常,如果你在使用过程中遇到问题请查阅BooleanQuery的使用方式。

/**
	 * 
	 * @function 删除
	 * @param id
	 *            资源Id
	 */
	public static void deleteDocument(Long id, String className) {
		DictItemBiz dictItemBiz = (DictItemBiz) ac.getBean("dictItemBiz");

		TermQuery idQuery = new TermQuery(new Term("id", id + ""));//删除的第一个域
		TermQuery resourceQuery = new TermQuery(new Term("type", dictItemBiz.getItemByDictMarkAndItemVal("search_type", className)
				.getItemId()
				+ ""));//删除的第二个域

		BooleanQuery bQuery = new BooleanQuery();
		bQuery.add(idQuery, BooleanClause.Occur.MUST);
		bQuery.add(resourceQuery, BooleanClause.Occur.MUST);
		// 自己的模块的索引更新
		String indexFilePath = FILE_PATH
				+ConfigurationManager.getInstance().getPropertiesValue(
						"common.properties", className + "IndexFilePath")
				+ "/index";
		try {
			deleteDocument(bQuery, indexFilePath);
		} catch (Exception e) {
			logger.error(e.getMessage());
		} finally {
			// 重新合并索引
			createModuleIndexAndSpellCheck();
		}
	}

	/**
	 * 
	 * @function 删除文档
	 * @param bQuery
	 * @param indexFilePath
	 * @throws Exception
	 */
	private static void deleteDocument(BooleanQuery bQuery, String indexFilePath) {

		indexWriter = MyIndexWriter.getInstance(indexFilePath, false);
		try {
			indexWriter.deleteDocuments(bQuery);
		} catch (Exception e) {
			logger.error(e.getMessage());
		} finally {
			MyIndexWriter.close();
		}
	}

使用IndexWriter更新索引

更新索引是一个删除再添加的过程,掌握添加和删除的技巧后,直接运用于更新即可。


使用IndexWriter更新索引合并多个索引文件

在创建索引的过程中,经常会使用不同的情况创建多个不同的索引文件,搜索的时候有时会搜索整个内容,这就需要使用合并索引的技术,虽然你可以创建索引的时候生成一个包含全部内容的索引文件,但是显然这是不合理的方法,这样会浪费大量的内存,在内容较多的情况下极易内存溢出。使用这种合并多个索引的方式使你的程序更加灵活可控。

合并索引文件的关键方法:addIndexesNoOptimize 但是现在Deprecated.use addIndexes(Directory...) instead


/**
	 * 
	 * @function 合并索引文件
	 * @param fromFilePaths 需要合并的索引文件路径
	 * @param toFilePath 合并完成的索引文件路径
	 */
	private static void mergeIndex(String[] fromFilePaths, String toFilePath) {
		IndexWriter indexWriter = null;
		File file = null;
		FSDirectory fsd = null;
		try {
			// System.out.println("正在合并索引文件!\t ");
			indexWriter = MyIndexWriter.getInstance(toFilePath + "/index",
					false);
			for (String fromFilePath : fromFilePaths) {
				file = new File(fromFilePath + "/index");
				if (file.exists()) {
					fsd = FSDirectory.open(file);
					indexWriter.addIndexesNoOptimize(fsd);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage());
		} finally {
			try {
				MyIndexWriter.close();
				if (fsd != null) {
					fsd.close();
				}
				file = null;
			} catch (Exception e) {
				e.printStackTrace();
				logger.error(e.getMessage());
			}
		}

	}






分享到:
评论

相关推荐

    lucene API最基本应用

    doc.add(new TextField("title", "Lucene教程", Field.Store.YES)); doc.add(new TextField("content", "这是关于Lucene的介绍", Field.Store.YES)); indexWriter.addDocument(doc); // 关闭 writer indexWriter....

    lucene4.0 demo

    在Lucene 4.0中,我们需要创建一个`Directory`对象来存储索引,常用的是`FSDirectory`,它将索引存储在文件系统中。接着,我们使用`IndexWriter`类,设定好分词器(Analyzer)和写入参数,然后逐个读取文档,调用`...

    最新Lucene教程

    3)document包相对而言比较简单,该包下面有3个类,document相对于关系型数据库的记录对象,Field主要负责字段的管理。 4)org.apache.1ucene.index索引管理,包括索引建立、删除等。索引包是整个系统核心,全文检索...

    关于lucene建立数据库索引的更新说明

    1. **资料的准确性**:由于网络上的信息繁多且质量参差不齐,使用Lucene时要确保所参考的教程或文档是最新的,因为版本更新可能导致某些方法或功能的改变。例如,旧版本中可能使用的`Hits`类在新版本中已被废弃,应...

    Lucene 搜索方法(布尔搜索)

    Lucene是一个高性能、全文本搜索库,它提供了强大的信息检索功能,而布尔搜索是其中一种常用且灵活的搜索方式,允许用户通过逻辑运算符(如AND、OR、NOT等)来组合多个查询条件,以精确地控制搜索结果。 描述部分...

    lucene开发资料.zip

    公用类通常包含了与Lucene交互的常用工具和辅助函数,比如索引创建、读取和更新的类,以及分词器和分析器的实现。配置文件则可能涉及到索引设置、内存管理、性能优化等方面,通过分析这些配置,开发者能更好地调整...

    Maven学习全教程.doc

    Maven学习全教程 Maven是一个基于项目对象模型(POM)的项目管理和构建自动化工具,由Apache软件基金会开发。Maven提供了一个统一的方式来构建、测试、打包和部署项目,使得项目的管理和维护更加容易。 结构概述 -...

    compass_使用详解.pdf compass_教程 compass_试用案例

    它通过提供类似于 Hibernate 的对象关系映射(ORM)功能,使得开发者能够更加轻松地将 Java 对象映射到 Lucene 索引上。与传统的 Lucene 相比,Compass 提供了更高级别的抽象和更简单的 API,从而降低了开发难度。 ...

    又是轮子(不过是自备): lucene3.0搜索数据库(最简单形式)

    3. **查询索引**:使用`Analyzer`和`QueryParser`来解析用户输入的查询,生成对应的`Query`对象。然后,通过`IndexSearcher`来执行查询,找到匹配的文档。 4. **获取结果**:`IndexSearcher`返回的搜索结果是一组`...

    68个常用开发手册

    DOM文档对象模型手册.chm DTD.chm EasyUI-API+1.3.2.chm Ext2.2API中文版.CHM Ext3.2中文API.CHM FILESLIST111.TXT Hibernate3.2.chm html5参考手册.chm HTML入门与提高.CHM Html标签一览表.chm html语法教程.chm ...

    图书管理系统 java ee 实用教程.zip

    SSH框架是Java EE开发中常用的三大框架集成,包括Struts负责控制层,Spring提供依赖注入和事务管理,Hibernate则是持久层的ORM(对象关系映射)工具。Struts作为MVC(模型-视图-控制器)设计模式的实现,负责请求的...

    常用的开发手册,都是chm格式,帮助文档,很好用

    9. **lucene_3.6.1_API.CHM**:Apache Lucene是一个全文搜索引擎库,此文档详细介绍了Lucene 3.6.1版本的API,包括索引构建、查询解析、搜索等功能。 这些CHM文件提供了丰富的编程和Web开发知识,对于学习和提升...

    开源企业搜索引擎SOLR的应用教程

    ### 开源企业搜索引擎SOLR的应用教程:详细知识点解析 #### 概述 Apache Solr是基于Lucene的高性能、可扩展的企业级全文搜索引擎。它提供了丰富的功能集,包括高度可配置的索引机制、强大的搜索功能以及分布式搜索...

    cassandra入门项目源代码

    【标题】:“Cassandra入门项目源代码”是一个针对初学者的教程项目,旨在帮助开发者了解如何在Eclipse环境中使用Spring Data框架与EasyRest风格来操作Cassandra数据库和Lucene搜索引擎。这个项目提供了一整套实践性...

    Solrj 中文教程

    最终,考虑到灵活性和扩展性等因素,本教程推荐使用Apache Solr作为企业级搜索引擎解决方案。 ##### 1.2 Solr的特性 **1.2.1 Solr使用Lucene并且进行了扩展** Solr基于Lucene实现,但增加了许多高级功能,例如...

    JAVA资料下载大全

    - 描述: Lucene是Java领域的全文搜索引擎库,本书介绍了如何使用Lucene构建搜索引擎。 - **链接**: http://bbs.topsage.com/dispbbs.asp?boardID=121&ID=173991 9. **Java Extreme Programming Cookbook** - ...

    solr教材-PDF版

    - **1.2.1 Solr使用Lucene并且进行了扩展**:Solr基于Apache Lucene构建,不仅继承了Lucene的强大功能,还提供了更高级别的分布式处理能力、更丰富的API支持等。 - **1.2.2 Schema(模式)**:Solr中的模式文件...

    齐鲁软件设计大赛作品简介

    - 《JSP实用教程》 - 《Lucene in Action》 这些资料覆盖了Web开发、XML处理、Java服务器页面技术以及全文检索库Lucene等方面的知识,为项目开发提供了理论基础和技术支持。 #### 二、总体设计 ##### 1. 需求概述...

    各种开发手册大全

    │ DOM文档对象模型手册.chm │ DTD.chm │ EasyUI-API+1.3.2.chm │ Ext2.2API中文版.CHM │ Ext3.2中文API.CHM │ Hibernate3.2.chm │ Hibernate3.2API.chm │ html5参考手册.chm │ HTML入门与提高.CHM │ Html...

Global site tag (gtag.js) - Google Analytics