lucene 索引技术

一、 Lucene索引创建和优化 [版本2.9.0以上]

Lucene索引的创建首先需要取得几个必须的对象:

1、分词器//可以采用其他的中文分词器
StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);//分词器

2、lucene目录
File dir = new File(indexDir);// indexDir为文件路径
//这种目录存在锁机制,在打开目录时,写的权利一次只分给一个用户;有效保证了索引文件不会因为多线程问题,同时写索引导致文件损坏。
Directory idxDir = new SimpleFSDirectory(dir, new SimpleFSLockFactory());

3、写索引对象
// isNewCreate为boolean值
IndexWriter writer = new IndexWriter(idxDir, analyzer, isNewCreate, IndexWriter.MaxFieldLength.LIMITED);

对writer对象可以做一些基本设置,以便优化数据操作。
writer.setMergeFactor(50); // 多少个合并一次【优化缓存】
writer.setMaxMergeDocs(5000); // 一个segment最多有多少个document【优化索引存储的segment文件】

4、document实例化和参数设置
writer可以写入的对象document也需要预先申明。
Document doc = new Document();
这个document是lucene自定义的一种存储节点对象。一个document可以包含N个filed域,N的取值可以在indexWriter定义的时候申明。各种域对应不同的应用场景。

//只存储,不做索引分析,value值就是唯一索引对应该条记录
Field field = new Field(key1, value1, Store.YES, Index.NOT_ANALYZED_NO_NORMS);
//存储,且做索引分析,value值被分析器解析成各种分词,一组索引对应该条记录
field = new Field(key2, value2, Store.YES, Index.ANALYZED);
//只存储,没有索引对应该域
field = new Field(key3, value3, Store.YES, Index.NO);

// 数字范围搜索
NumericField numericField = new NumericField(key4, Store.YES, true);
numericField.setLongValue(value4);

域生成之后通过document的add方法添加到一个document对象中。
//document 域的添加
doc.add(field);
doc.add(numericField);


5、对索引的写操作和优化操作关键步骤如下

writer.addDocument(doc);//向索引文件中写数据
writer.optimize();// 索引优化,一般执行此步骤时,所消耗的内存是写入索引所需内存的2倍,在执行索引生成操作的时候本身就对内存有比较大的消耗,最好在索引创建完成之后,执行此步骤。
writer.commit();//数据提交
writer.rollback();//数据回滚
writer.close();//关闭流索引写入器,此步骤才真正将数据写入到索引文件中。


二、 Lucene索引实现 精确查询 分词查询 范围查询 多条件查询等

查询的步骤实现:

1、首先需要设置查询条件参数。
BooleanQuery query = new BooleanQuery();// 多条件查询 处理检索条件

Query termQuery = new TermQuery(new Term(key,value)); // 基本/精确 查询
query.add(termQuery, Occur.MUST);// 根据索引中的document生成时的设置,可以实现精确记录

/* 范围查询 */
Query numericRangeQuery = NumericRangeQuery.newLongRange(key, minValueLong, maxValueLong, true, true);
query.add(numericRangeQuery, Occur.MUST); // numericRangeQuery是按数值范围匹配

/* 多域组合查询 */
BooleanClause.Occur[] occurs =
new BooleanClause.Occur[] { BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD };
Query multiFieldQuery = MultiFieldQueryParser.parse(keyWord, new String[] { key1, key2 }, occurs, analyzer);
query.add(multiFieldQuery, Occur.MUST);// multiFieldQuery是把关键字keyWord分别在key1和key2中匹配 组合查询

2、创建索引搜索器。
//以只读方式,创建索引搜索器
IndexSearcher searcher = new IndexSearcher(idxDir, readOnly);//readOnly 为boolean值

3、设置排序条件。
//设置根据哪个域的key来排序
SortField field = null;
// Long型降序
field = new SortField(key, SortField.LONG, true);
// Long型升序
field = new SortField(key, SortField.LONG, false);
// 搜索引擎权重
field = new SortField(null, SortField.SCORE, true);//不需要指定域的key来排序,lucene中会根据查询结果出现的次数给每个结果设置排序参数,搜索结果会按照这个排序参数的大小来由大到小进行排序。【即为搜索结果热门程度的降序排列】

// Integer型排序
field = new SortField(key, SortField.INT, true);

// 单条件排序
Sort sort = = new Sort(field);

// 多条件排序
SortField[] fields = new SortField[] { field1, field2 };
Sort sort = = new Sort(fields);

4、执行查询操作,并处理获得查询结果

//查询获取结果
// 查询 searcher.maxDoc()为searcher中所包含的最大document下标值 filter为过滤器[没有的话,一般写null]
TopFieldDocs docs = searcher.search(query, filter, searcher.maxDoc(), sort);
ScoreDoc[] scoreDocs = docs.scoreDocs;//权值对象 包含document下标信息,能确定searcher中的document的下标。
int docCount = scoreDocs.length;//查询结果统计
// 取出最后一个查出的document对象
Document doc = searcher.doc(scoreDocs[docCount - 1].doc); // 通过document下标值,获取document对象
开源全文搜索工具包Lucene2.9.1的使用。 1. 搭建Lucene的开发环境:在classpath中添加lucene-core-2.9.1.jar包 2. 全文搜索的两个工作: 建立索引文件,搜索索引. 3. Lucene索引文件逻辑结构 1) 索引(Index)由若干块(片段)(Segment)组成 ★2) 块由若干文档(Document)组成: 一个文件映射成一个文档。数据库表中的一条记录映射成一个文档。 ★3) 文档由若干域(Field)组成:文件的属性(文件路径,文件的内容)映射成一个域。记录的某个字段映射成一个域。 ☆4) 域由若干词(关键字)(Term)组成:文件的属性的内容中某个字符串映射成一个词。 4. Lucene包结构 1) analysis模块:负责词法分析及语言处理而形成Term(词)。提供了一些内置的分析器:最常用的是StandardAnalyzer 2) index模块:负责索引的读写。 对索引文件的segment进行写、合并、优化的IndexWriter类。对索引进行读取和删除操作的IndexReader类。 3) store模块:负责索引的存储。提供索引的各种存储类:FSDirectory,RAMDirectory等。 4) document模块:索引文件内部的基础存储结构封装。如:Document类和Field类等。 5) search模块:负责对索引的搜索。提供了索引搜索器IndexSearcher类和各种Query类,如TermQuery、BooleanQuery等。 6) queryParser模块:负责查询语句的语法分析。提供了解析查询语句的QueryParser类 7) util模块:包含一些公共工具类。 5. 创建索引 1) IndexWriter:索引写出器 a) 构造方法: IndexWriter(Directory d, Analyzer a, IndexWriter.MaxFieldLength mfl) 如果索引不存在,就会被创建。如果索引存在,就追加. IndexWriter(Directory d, Analyzer a, boolean create, IndexWriter.MaxFieldLength mfl) create为true时,原索引文件不存在就创建,存在就覆盖。 create为false时,原索引文件不存在就报错,存在就追加。 b) 常用方法: void addDocument(Document doc); //把指定文档添加到索引写出器中 void iw.close(); //关闭索引写出器,此时才把索引写到目标存储地 2) Directory: 索引存放地。 a) 文件系统:FSDirectory: FSDirectory.open(File file); b) 内存RAMDirectory: new RAMDirectory(); 3) Analyzer: 分词器。 a) StandardAnalyzer: 标准分词器。对英文采用空白, 标点符号进行分词。对中文采用单字分词。 b) SmartChineseAnalyzer: 智能中文分词器。(LUCENE_HOME/contrib/analyzers/smartcn/lucene-smartcn-2.9.1.jar) C) 第三方的中文分词器:如PaodingAnalyzer、IKAnalyzer 4) IndexWriter.MaxFieldLength: 指定域值的最大长度。 a) UNLIMITED 无限制的。 b) LIMITED 有限制的。值为10000 5) Document: 索引的组成单元. 一组Field的集合. a) 构造方法: Document(); b) 常用方法: void add(Field f); //添加指定域到这个文档中 6) Field: 域,代表文档的某个索引域. a) 构造方法: Field(String name, String value, Field.Store.YES, Field.Index.ANALYZED) name: 域的名称, 只能是字符串. value: 域的值, 只能是字符串. Field.Store: 指定Field的值是否存储或怎样存储. NO(不存储), YES(存储),COMPRESS(压缩后存储) Field.Index: 指定Field是否被索引或怎么被索引. NO(不索引), ANALYZED(分词后索引), NOT_ANALYZED(不分词直接索引)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值