`
dingjun1
  • 浏览: 208364 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

lucene应用入门1

阅读更多
简单的建立索引和索引查询
org.apache.lucene.index
                   ---IndexWriter

一个IndexWriter创建和维护一个index

参数create会建议构造方法,决定是一个新的index被创建,或打开一个已经存在的index。
甚至IndexReader正在使用这个Index,你也可以设置create=true打开该index,旧的IndexReader 对象会继续查询已经使用“时间点”快照的index,不会看到最新的创建的Index直到IndexReader对象被重新打开.
IndexWriter也可以不使用create参数构造对象,如果在提供给该对象路上Index不存在,IndexWriter对象会创建一个新的索引,否则会打开一个存在的Index。

在上述两种情况中,使用addDocument()增加documents,使用deleteDocuments(Term)或deleteDocuments(Query)移除documents,使用updateDocument()更新document(更新仅仅是删除后添加整个document),在完成文档增删改后,应该调用close()文法关闭IndexWriter.

这些变更会缓存在内存中,定期地flush到Directory,从最近一次flush后当删除的document被缓存到一定量时( setMaxBufferedDeleteTerms(int)),或者添加的document缓存到一定的量,flush会被触发调用。添加documents时,用于存放document内存容量(setRAMBufferSizeMB(double))或数目达到设定的量都会触发flush。默认当内存容量达到16MB会触发flush。你可以通过设定一个大的内存容量提高建立索引的速度。注意,刷新缓冲时,只移除在IndexWriter对象内的缓存状态,输出到INDEX。这些改变在执行commit或close前,对IndexReader是不可见的。一次缓存输出可能引发一次或多次segment合并,合并默认运行在后台的一个线程中,因此不会阻断addDocument的调用。

构造方法的可以选择的autoCommit方法控制IndexReader对象感知同一个index的更改,当为false,更改不会被感知,直到调用close()或commit(),更改会做为一个新的

文件被冲刷到directory,但是不会执行(不会有新的segments_N 文件引用新的文件进行写操作,也不会同步进行持久存储),直到close()被调用。在调用close()前,某个原因导致了一个严重的错误,index不会更改(它会保持它开

始时的状态),你也可以调用rollback(),关闭写入流,不会提交任何的更改,同时删除所有flush而没有被使用的index文件。这是很有用的对实行简单的单一写事务性的semantics.你可以做两个阶段的提交,调用commit()前先调用prepareCommit()。当LUCENE与外部资源(比如:数据库)一起工作时,两个必须一起提交或者回退事务。

当autoCommit为true是,IndexWriter对象会周期性的自己提交(Deprecated:3.0,IndexWriter 将不会再接受autoCommit=true,这会引起hardwire失败)。你可以根据需要一直调用commit()。不能保证自动执行会被执行(这个被使用在每次完全合并后。Version2.4)如果强制提交可以调用commit()或者关闭writer。当运行在这种模式下,注意在优化或者进行segment合并时不要刷新reader,这会占用大量的磁盘空间。
无论是不是autoCommit,IndexReader或者IndexSearcher只会看到在Index打开时的那个时间点的内容。任何在reader打开后提交的内容,对其是不可见的,直到reader被重新打开。

如果Index不会添加大量的documents,同时需要最佳的查询性能,这时用于全部优化的optimize()方法或者用于部分优化的optimize(int)方法应该在Index关闭前调用。

IndexWriter对象在使用中,会生成一个对目录的锁文件,试着在同一个目录打开另一个IndexWriter对象将会导致LockObtainFailedException。如果一个IndexReader对象在同一个目录用于从索引中删除documents时,这个异常也会被抛出。


org.apache.lucene.document
----Document
Document 是建索引和查询的功能单位,一个Document是一组field,每一个field有一个名称和一个文本值,一个field可能存放在Document中,它是

在Document中被查询命中后做为返回值,因此每一个document应该代表性包含一个或多个存储型的field用来唯一标识它。
field没有被存储在document中,不允许从索引中取回(比如使用ScoreDoc.doc Searcher.doc(int) IndexReader.document(int))

Document doc = new Document();
doc.add(Fieldable field)添加一个field到document中
String doc.get(String name),返回指定名称field的字符值,如果不存在则返回NULL
Fieldable doc.getField(String name)返回给定名称的field,如果不存在则返回null
doc.removeField(String name)移除给定名称的field
List getFields()返回在Document中的所有field
doc.setBoost()//设置权重因子


java.lang.Object
  org.apache.lucene.document.AbstractField
      org.apache.lucene.document.Field
----Field
field是document中的一部分,每一个field有两个部分,名称和值,值可以是做为字符串或者Reader流提供,它们可能是一个原子性的关键字,

它不用进一步处理,这些关键字可能是日期,链接等,字段被选择性地存储在索引中,以使它们可能做为document中的命中点被返回。
Field.Index:详细指明这个field是否要建索引,或者以什么样的方式建索引
Field.Index.NO:不对这个字段建索引,因此这个字段是不会被查询到的,如文档的路径、属性可能我们不想让它被检索到
Field.Index.NO_NORMS:建立索引,但是不对它进行分词索引,存储的规范不起作用,索引时,将不考虑权重因子和Field长度标准,优点就

是它占较小的内存,所在的字段开始索引时都是这种状态。(Index the field's value without an Analyzer, and disable the storing of

norms. No norms means that index-time boosting and field length normalization will be disabled. The benefit is less memory usage as

norms take up one byte per indexed field for every document in the index. Note that once you index a given field <i>with</i> norms

enabled, disabling norms will have no effect. In other words, for NO_NORMS to have the above described effect on a field, all

instances of that field must be indexed with NO_NORMS from the beginning.)
Field.Index.TOKENIZED:分词建索引
Field.Index.UN_TOKENIZED:不使用分词器对其值建索引,如日期,作者等
Field.Store:详细指明这个field是否存储,或都以什么样的方式存储。
Field.TermVector:条件向量

Field(String name, Reader reader) :分词索引,但是不存储,相当于Field(String name,String

value,Field.Store.NO,Field.Index.TOKENIZED)
Field(String name, String value, Field.Store store, Field.Index index) :指定存储情况、索引情况。
Field(String name, String value, Field.Store store, Field.Index index, Field.TermVector termVector) :



org.apache.lucene.search.Searcher
      org.apache.lucene.search.IndexSearcher
应用常常只需要通过Searcher.search(Query) 或者Searcher.search(Query,Filter)的方法继承得到。由于执行效率的原因,推荐在使用所有的查询

时,只打开同一个IndexSearcher。
注意:你只能在IndexSearcher没有关闭的期间,可以访问命中点集合,或则会抛IOException


org.apache.lucene.queryParser.QueryParser
这个类是,由JAVACC产生,最重要的方法就是parse(String),查询语法如下:
加号(+)或是减号(-),分别标志一个必须的条件或者一个禁用的条件,
由一个冒号(:)开头的条件,表示查询的field,这能够构造一个查询多个field的查询。

查询的句子可能是其中一种:
一个条件,表示所有的document符合这个条件,或者是一个嵌套的查询,由括号包裹,用+\-做为前缀使用于一组条件
查询语法如下:
Query ::=(Clause)*
Clause ::= ["+","-"][<TERM>":"](<TREM>|"("QUERY")")

评分机制
如果你想对每一个查询都设置权重因子在(评分时加大权重)标题field,使用你的查询句子用Query.setBoost()设置权重因子在你的标题field是最容

易的。
Field.setBoost()应该只使用在不同的Document中给不同的field设置权重因子时才使用,所以在查询时给所有的标题加相同的数值的权重因子是比较

容易的。这种方式可以试验权重数值,而不用重建索引,Field.setBoost()设置的值被建立在索引中,因而很难被改变。因此我推荐使用

Query.setBoost()来代替,为每一个查询的field构造成一个Query(自己编码,或者使用QueryParser),单独为每一个查询的field设置权重因子,然

后在执行时,联合这些查询建立一个逻辑查询(BooleanQuery)。我想这是有意义的。
If you wish to boost the title field for every query then it would be
easiest to boost the title clause of your query, with Query.setBoost().
Field.setBoost() should only be used when you want to give a field
different boosts in different documents, but since you want to boost all
titles by the same amount, you'll find it easier to boost at query time.
That way you can experiment with the boost amount without re-building
the index.  The values of Field.setBoost() are built into the index and
are harder to change.  Thus I recommend using Query.setBoost() instead.
Construct a query for each field to be searched (by hand, or with the
QueryParser), boost each of these field queries separately, then build a
BooleanQuery that combines these into a single Query that you then
execute.  I hope that makes sense.

package learn;


/**
 * 建立索引
 * @author Administrator
 *
 */
import java.io.*;
import org.apache.lucene.index.*;
import org.apache.lucene.store.*;
import org.apache.lucene.analysis.standard.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.cn.*;
import org.apache.lucene.document.*;

public class BuildIndex {
	private final static String INDEX_DIR_PATH="e:\\index";
	private final static String test_dir="e:\\txt";
	/**
	 * @param args
	 */
	/**
	 * 获得IndexWriter对象
	 */
	public IndexWriter getIndexWriter(Directory indexDir,Analyzer analyzer) throws IOException{
		return new IndexWriter(indexDir,false,analyzer,true);
	}
	
	/**
	 * 建立索引
	 * @throws IOException
	 */
	public void build() throws IOException {
		Directory indexDir = FSDirectory.getDirectory(INDEX_DIR_PATH);
		Analyzer analyzer = new ChineseAnalyzer();
		
		IndexWriter writer = getIndexWriter(indexDir,analyzer);
		indexFile(writer,new File(test_dir));
		writer.flush();
		writer.optimize();
		writer.close();
		
		
	}
	
	/**
	 * 索引所有文件
	 * @param writer
	 * @param f
	 * @throws IOException
	 */
	public void indexFile(IndexWriter writer,File f) throws IOException{
		
		if(!f.exists()){
			throw new IOException("文件不存在");
		}
		if(f.isDirectory()){
			File[] fArr = f.listFiles();
			for(int i=0;i<fArr.length;i++){
				indexFile(writer,fArr[i]);//递归
			}
		}else{
			FileReader fr = new FileReader(f);
			Document doc = new Document();
			doc.add(new Field("content",fr));//建立索引,不存储
			doc.add(new Field("path",f.getAbsolutePath(),Field.Store.YES,Field.Index.NO));//存储不建索引
			writer.addDocument(doc);//添加记录
		}
	}
	
	public static void main(String[] args) throws IOException{
		BuildIndex build = new BuildIndex();
		build.build();

	}

}



package learn;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cn.ChineseAnalyzer;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.queryParser.*;
import org.apache.lucene.document.*;
import java.io.*;

public class TestSearch {
	private static IndexSearcher searcher = null;
	private final static String INDEX_DIR_PATH="e:\\index";
	
	public IndexSearcher getInstance() throws IOException{
		if(searcher==null){
			Directory indexDir = FSDirectory.getDirectory(INDEX_DIR_PATH);
			
			searcher = new IndexSearcher(indexDir);
		}
		return searcher;
	}
	
	/**
	 * 查询
	 * @param searchStr
	 * @throws IOException
	 * @throws ParseException
	 */
	public void search(String searchStr) throws IOException,ParseException{
		Analyzer analyzer = new ChineseAnalyzer();
		Query q =new QueryParser("content",analyzer).parse(searchStr);
		Hits hits = getInstance().search(q);
		HitIterator it = (HitIterator)hits.iterator();
		while(it.hasNext()){
			Document doc = ((Hit)it.next()).getDocument();
			System.out.println("path:"+doc.getField("path")+"");
		}
	}
	
	
	public static void main(String[] args) throws IOException,ParseException{
		TestSearch test = new TestSearch();
		test.search("网页 OR 服务器");
	}
	
}

分享到:
评论

相关推荐

    Lucene入门demo

    Lucene入门demo,lucene简单的应用

    lucene-入门

    概述 Lucene简介 Lucene架构原理 Lucene应用示例(Hello World)

    Lucene快速入门

    Lucene是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。Lucene以其方便使用、快速实施以及灵活性受到广泛的...它可以方便地嵌入到各种应用中实现针对应用的全文索引、检索功能,本总结使用lucene--2.3.2。

    lucene学习

    Lucene的基础知识 1、案例分析:什么是全文检索,如何实现全文检索 2、Lucene实现全文检索的流程 a) 创建索引 b) 查询索引 3、配置开发环境 ...Lucene的高级查询、solr入门 solr在项目中的应用及电商搜索实现

    Lucene介绍视频教程

    Lucene入门精讲视频教程QQ截图20191025020202.png?x-oss-process=style/pnp8(39.97KB,下载次数:225)下载附件2019-10-2502:02上传〖课程介绍〗:Lucene是apache下的一个开放源代码的全文检索引擎工具包。提供了完整的...

    lucene简单介绍及solr搭建使用

    lucene的应用.pdf 01solr企业级搜索引擎准备阶段.pdf 02solr企业级搜索引擎实战演练.pdf 适合新手搭建solr使用

    lucene笔记

    1、 Lucene介绍 a) 什么是lucene b) 全文检索的应用场景 c) 全文检索定义 2、 Luence实现全文检索的流程(重点) 3、 入门程序 4、 Field域(重点) 5、 索引维护 a) 添加索引 b) 删除索引 c) 修改索引 6、 搜索...

    Lucene.docx

    lucene基础使用,基础知识,入门级了解用,Lucene和其他一些全文检索系统/应用的比较,语言的的切分词问题,索引过程优化

    深入理解Luncen搜索引擎开发

    第1章 Lucene初识 Lucene4入门精通实战课程概述 Lucene系统架构 第2章 Lucene索引 Lucene索引里有什么 Lucene索引深入 Lucene索引深入优化 Lucene索引搜索 第3章 Lucene搜索实战 Lucene搜索实战 Lucene搜索深入...

    基于Java的全文检索引擎简介

    基于Java的全文检索引擎简介,Lucene快速入门

    Lucene全文检索从入门到精通(精细讲解含代码笔记答疑服务)

    Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎...

    傻瓜索引搜索v1.1[含全部源代码]

    傻瓜索引搜索系统v1.1的全部源代码。 基于Lucene.Net。主要目的就是包装Lucene.Net 使其应用简单化。 包括两个范例web一个,控制台一个。 没有高亮显示这个部分。...不过很多高级内容没有应用进去,适合入门。

    Lucene教学视频从入门到精通(备java基础,javase。javaee)

    Lucene是apache下的一个开放源代码的全文检索引擎工具包。提供了完整的查询引擎和索引引擎。...Lucene和搜索引擎不同,Lucene是一套用java或其它语言写的全文检索的工具包,为应用程序提供了很多个api接口去调用。

    Lucene+ElasticSearch入门至项目实战(Java高级、架构师必备套餐)

    1、熟练掌握Lucene框架的使用,实现类似百度、京东商城等应用的全文检索效果; 2、ElasticSearch下载安装(window以及linux下安装) 3、集群环境搭建 4、客户端Kibana安装与使用 5、集群管理插件head安装使用 6、...

    大数据基础知识入门.pdf

    大数据基础知识入门 社会保障事业部 张火磊 主要内容 大数据价值 03 大数据概念、特性、由来 01 大数据应用举例 04 02 Hadoop技术介绍 大数据概念、特性、由来 什么叫大数据? 麦肯锡全球研究所给出的定义是:一 种...

    Nutch入门.rar

    1.4 nutch VS lucene.....2 2. nutch的安装与配置.....3 2.1 JDK的安装与配置.3 2.2 nutch的安装与配置........5 2.3 tomcat的安装与配置......5 3. nutch初体验7 3.1 爬行企业内部网....7 3.1.1 配置nutch.....

    ELK入门到精通

    它构建于Apache Lucene搜索引擎库之上。 Logstash是一个用来搜集、分析、过滤日志的工具。它支持几乎任何类型的日志,包括系统日志、错误日志和自定义应用程序日志。它可以从许多来源接收日志,这些来源包括 syslog...

    Hadoop源码的入门解析

    Hadoop原来是Apache Lucene下的一个子项目,它最初是从Nutch项目中分离出来的专门负责分布式存储以及分布式运算的项目。简单地说来,Hadoop是一个可以更容易开发和运行处理大规模数据的软件平台。下面列举hadoop主要...

    irene:到Galago 3.16和Lucene 7的静态类型查询接口

    #inquery提供给我们的内容是Lemur项目搜索引擎(Indri和Galago)的“杀手级应用”。 我们如何使它更小,更便携,对研究人员更有用? 将其与后端分开。 该项目处于非常早期的Alpha状态: 我还没有开放它的真正意图...

    Liferay入门帮助文档(Liferay开发指南)

    基于J2EE的应用,使用了EJB以及JMS等技术,前台界面部分使用Struts MVC 框架,基于XML的portlet配置文件可以自由地动态扩展,使用了Web服务来支持一些远程信息的获取,使用 Lucene实现全文检索功能。 Liferay国内用...

Global site tag (gtag.js) - Google Analytics