- 浏览: 10810 次
- 性别:
- 来自: 厦门
最新评论
lucene各个模块用途
建立索引和检索图解
以一个Demo来查看查询代码粗略逻辑
Document.add()方法流程
这个方法主要功能是将field字段和值保存到缓存中去,等待close()方法调用时写入文件。其中为了增加效率启用了多线程创建索引分词。分词组件可以自己实现只要继承Analyzer类。在分词组件里面重载incrementToken(不大记得好像是)或者自己实现一个类继承Tocken,在类里面重载incrementToken方法。这样,如果索引字段的定义了需要分词的话,就会调用你重载的这个方法,以此实现自定义分词效果。
看了4.9+的代码,这个方法以及被定义为final。作者开发了另一个方法来提供用户重载,实现一样效果。
下面贴一个程序运行的关键代码,以及基于4.7.0实现的一个Analyzer.
writer.close()方法的流程(用画图工具画的,超级烂。下次引以为戒)
关键的一部分代码:
英文单词大小写处理
lucene用他自带的standardAnalyzer在建立索引的时候是区分大小写的。在查询query的时候会通通转成小写,导致查询不到。那么可以复制一份源代码,放到本地改一下。调用本地就可以
参考:
因为lucene虽然版本升级,方法上有很多改变,我感觉用户体验明显好多了。但是目前他整体的架构没看得大改变。所以以前的一些书籍还是可以看得。记录一下文档地址,这是一本很好的书:http://www.open-open.com/doc/view/f92fa668d8b84626abd20a05b6eb014e
建立索引和检索图解
以一个Demo来查看查询代码粗略逻辑
public class TestDemo extends LuceneTestCase { public void testDemo() throws IOException, ParseException { //创建一个分词器使用Whitespace-lowercasing analyzer,且无停用词. Analyzer analyzer = new MockAnalyzer( random); //保存索引到内存: //Directory directory = newDirectory(); //会创建2个文件segements.gen(内容为索引的field字段)/segement_N(内容为空) // 如果要保存到硬盘,用下面替换: Directory directory = FSDirectory. open( new File("D:\\index" )); RandomIndexWriter iwriter = new RandomIndexWriter( random, directory, analyzer); //maxFieldLength 长度溢出将在这里打印 iwriter.w.setInfoStream(VERBOSE ? System. out : null); //新建文档 Document doc = new Document(); //需要索引的值 String text = "This is the text to be indexed."; //建立索引,此时不创建文件放内存,第三个参数设置用来判断是否要分词。 doc.add(newField("fieldname" , text, Field.Store.YES, Field.Index.ANALYZED)); //创建2个文件.fdt.ftx但是没有填充值 iwriter.addDocument(doc); //这里默认commit了,填充了值,合并段,合并文档等,还创建了其他各种文件 iwriter.close(); // 查询索引: IndexReader ireader = IndexReader.open(directory); // read-only=true IndexSearcher isearcher = new IndexSearcher(ireader); //创建个默认查询,文字:"text": QueryParser parser = new QueryParser( TEST_VERSION_CURRENT, "fieldname", analyzer); Query query = parser.parse("text"); TopDocs hits = isearcher.search(query, null, 1); // 循环结果集: for (int i = 0; i < hits. scoreDocs. length; i++) { Document hitDoc = isearcher.doc(hits. scoreDocs[i]. doc); assertEquals("This is the text to be indexed." , hitDoc.get("fieldname")); } // 测试短语 query = parser.parse("\"to be\""); assertEquals (1, isearcher.search(query, null, 1).totalHits); //记得手动关闭 isearcher.close(); ireader.close(); directory.close(); } }
Document.add()方法流程
这个方法主要功能是将field字段和值保存到缓存中去,等待close()方法调用时写入文件。其中为了增加效率启用了多线程创建索引分词。分词组件可以自己实现只要继承Analyzer类。在分词组件里面重载incrementToken(不大记得好像是)或者自己实现一个类继承Tocken,在类里面重载incrementToken方法。这样,如果索引字段的定义了需要分词的话,就会调用你重载的这个方法,以此实现自定义分词效果。
public TokenStream reusableTokenStream(String fieldName, Reader reader) throws IOException;
看了4.9+的代码,这个方法以及被定义为final。作者开发了另一个方法来提供用户重载,实现一样效果。
protected Analyzer.TokenStreamComponents createComponents(String fieldName, Reader reader);
下面贴一个程序运行的关键代码,以及基于4.7.0实现的一个Analyzer.
//保证多个进程同时读取Directory不出问题。对一个lockFactory的引用来锁定文件 public abstract class Directory implements Closeable { protected LockFactory lockFactory; } //锁定文件,因为采用多个线程同时进行分词,同时只能有一个线程对缓存进行读写 public abstract class LockFactory { public abstract Lock makeLock(String lockName); abstract public void clearLock(String lockName) throws IOException; } //保存索引文件的原文档 public final class Document implements java.io.Serializable { List<Fieldable> fields = new ArrayList<Fieldable>(); } //分词组件,有2个重载方法。功能:1、分词。2、停词。3、去掉标点。可以自己实现分词 public final class MockAnalyzer extends Analyzer { private final int pattern; private final boolean lowerCase; private final CharArraySet filter; private final boolean enablePositionIncrements; private int positionIncrementGap; private final Random random; private Map<String,Integer > previousMappings = new HashMap<String,Integer>(); private boolean enableChecks = true; private int maxTokenLength = MockTokenizer.DEFAULT_MAX_TOKEN_LENGTH ; maybePayload() { //影响词的评分 token.setPayload(new PayLoad((Field)_id.getByte())); } //这个方法返回一个TokenStreamComponents,设置reader,filters,token。(lucene4.10这个方法为final不可继承) public TokenStream reusableTokenStream(String fieldName, Reader reader) throws IOException { @SuppressWarnings("unchecked" ) Map<String,SavedStreams> map = (Map) g etPreviousTokenStream(); if (map == null) { map = new HashMap<String,SavedStreams>(); setPreviousTokenStream(map); } SavedStreams saved = map.get(fieldName); if (saved == null) { saved = new SavedStreams(); saved.tokenizer = new MockTokenizer(reader, pattern, lowerCase, maxTokenLength); saved.tokenizer.setEnableChecks( enableChecks); StopFilter filt = new StopFilter(LuceneTestCase.TEST_VERSION_CURRENT , saved.tokenizer , filter); filt.setEnablePositionIncrements(enablePositionIncrements ); //这里用的是责任链模式。类似saved.filter=A,A.filter=B,B..filter=c以此类推 saved.filter = filt; //是否使用跳跃表,不设置的话,如果索引一旦增长(根据分词判断是否使用同一个字典链表)过长,lucene会自动使用。 saved.filter = maybePayload(saved. filter, fieldName); //关键是这一行,将filter放入map,可以放入多个,类型为TokenFilter map.put(fieldName, saved); return saved. filter; } else { saved.tokenizer.reset (reader); return saved. filter; } } } //filter超类 public class Token { //默认对是否进行使用跳跃表的实现 private Payload payload; }
writer.close()方法的流程(用画图工具画的,超级烂。下次引以为戒)
关键的一部分代码:
//创建、写入文件segments public class IndexWriter implements Closeable, TwoPhaseCommit { //这里创建segments.gen,segments_N文件以及保存数据 private synchronized final void finishCommit() throws CorruptIndexException, IOException { pendingCommit .finishCommit(directory); } //入口 private void closeInternal(boolean waitForMerges) throws CorruptIndexException, IOException { //创建各种文件,(除segments*,.fdt.fdx),先组装数据,后合并数据,写入文件操作 flush(waitForMerges, true); //会调用到finishCommit() commitInternal(null); } }
英文单词大小写处理
lucene用他自带的standardAnalyzer在建立索引的时候是区分大小写的。在查询query的时候会通通转成小写,导致查询不到。那么可以复制一份源代码,放到本地改一下。调用本地就可以
protected TokenStreamComponents createComponents(final String fieldName, final Reader reader) { final StandardTokenizer src = new StandardTokenizer(matchVersion, reader); src.setMaxTokenLength(maxTokenLength); src.setReplaceInvalidAcronym(replaceInvalidAcronym); TokenStream tok = new StandardFilter(matchVersion, src); //注释掉这一句 //tok = new LowerCaseFilter(matchVersion, tok); tok = new StopFilter(matchVersion, tok, stopwords); return new TokenStreamComponents(src, tok) { @Override protected boolean reset(final Reader reader) throws IOException { src.setMaxTokenLength(StandardAnalyzer.this.maxTokenLength); return super.reset(reader); } };
参考:
因为lucene虽然版本升级,方法上有很多改变,我感觉用户体验明显好多了。但是目前他整体的架构没看得大改变。所以以前的一些书籍还是可以看得。记录一下文档地址,这是一本很好的书:http://www.open-open.com/doc/view/f92fa668d8b84626abd20a05b6eb014e
发表评论
-
(转)SPDY、HTTP/2、QUIC协议
2015-04-27 19:53 11371 SPDY协议 1.1 概述SPDY为s ... -
svn与apache dbd整合
2015-04-23 14:54 624准备工作 cd .. bzip2 -dc temp/apr- ... -
mybatis报找不到类
2015-03-26 17:36 2375调用mybatis时参数类型为一个包含动态内部类的参数类型,那 ... -
NIO和NodeJs中基于事件的异步调用
2015-03-24 15:33 822异步 目前的异步执行不管是js还是java,都并不是真正的异步 ... -
各种可用的util类
2015-03-21 10:59 0在jdk和spring中有许多我们可以直接使用的util类。 ... -
jvm学习(笔记)
2015-03-17 21:56 4631、jvm规范 2、Oracle Jdk 编译机制 ... -
本地缓存实现
2015-03-11 15:59 628最近做了个东西,使用的数据是根据元数据进行读取和加工,加工后又 ...
相关推荐
这个“lucene基本包”包含了Lucene的核心组件,是理解和使用Lucene进行信息检索的基础。 1. **全文检索引擎架构** Lucene的核心理念是建立索引,以便快速查找文档中的信息。它通过将文本数据转换成便于搜索的结构...
一、Lucene基本架构 1. 文档索引:Lucene的核心工作是将非结构化的文本数据转换为结构化的索引。这一过程包括分词(Tokenization)、词干提取(Stemming)和停用词处理(Stop Word Filtering),以及创建倒排索引...
一、Lucene基本架构 1. 文档索引:Lucene首先对文档进行索引,将文本数据转换成便于搜索的数据结构。这个过程包括分词(Tokenization)、词干提取(Stemming)、停用词处理(Stop Word Removal)等预处理步骤,以及...
一、Lucene的架构与工作原理 Lucene的核心概念包括文档(Document)、字段(Field)、索引(Index)和查询(Query)。首先,每个文档由一个或多个字段组成,字段内可以包含文本、数字或其他类型的数据。接着,...
2. **词项(Term)**:每个分词后的词汇单元称为词项,是Lucene索引的基本单位。词项由一个词典中的词汇(如“apple”)和文档中出现的位置(或位置编码)组成。 3. **词典(Dictionary)**:词典是所有唯一词项的...
而在Lucene中,基本单位是Document,它同样由多个字段组成,但Lucene索引的是这些字段的内容,以加速文本检索。 - **索引构建**:Lucene支持增量索引和批量索引,可以处理数据源的小幅变化或大规模数据。数据库通常...
通过阅读书中的第1章“LUCENE基础”,读者可以建立起对Lucene基本架构和工作流程的初步认识,为进一步的学习打下坚实基础。 总之,《Lucene搜索引擎开发权威经典》是一本全面介绍Lucene的书籍,适合想要从事搜索...
- **索引(Index)**: Lucene 首先需要对文档进行索引,将文本数据转换为可搜索的结构。索引是倒排索引,其中每个单词都指向包含该词的文档列表。 - **文档(Document)**: 文档是 Lucene 中的基本单位,可以代表...
### Lucene基本使用详解 #### 一、概述 在当今数据爆炸的时代,如何从海量的信息中快速找到所需的内容成为了一项重要技能。全文检索技术便应运而生,旨在提高信息检索的效率与准确度。Lucene是一款由Apache基金会...
一、Lucene基本架构 Lucene的核心架构主要包括以下几个关键组件: 1. 文档(Document):文档是信息的基本单元,可以包含多个字段(Field),如标题、内容等。每个字段有其特定的类型,如文本、日期等。 2. 索引...
**LUCENE搜索引擎基本工作原理** Lucene是一个开源的全文搜索引擎库,被广泛应用于构建复杂的搜索引擎系统。它的设计目标是高效、灵活且可扩展。理解Lucene的工作原理有助于开发人员更好地利用这一强大的工具。 **...
该文档详细阐述了Lucene的架构设计,包括其核心组件如Analyzer(分析器)、Document(文档)、IndexWriter(索引写入器)和Searcher(搜索器)的工作原理。理解这些组件如何协同工作,有助于你更好地利用Lucene进行...
一、Lucene的基本架构 Lucene的核心架构主要分为三个部分:索引(Indexing)、查询(Query)和搜索(Searching)。首先,索引过程将原始文档转换为倒排索引(Inverted Index),这是一个经过优化的数据结构,便于...
- **基本概念**:介绍Lucene索引文件的基本术语和概念。 - **基本类型**:定义了索引文件中使用的数据类型。 - **基本规则**:阐述了文件格式设计的基本原则。 - **具体格式**: - **正向信息**:包括段元数据、...
通过阅读《Annotated Lucene 中文版 Lucene源码剖析》,读者不仅能掌握Lucene的基本使用,还能深入了解其底层原理,从而更好地利用和扩展这个强大的搜索工具。 总之,对于想要提升信息检索技术的Java开发者来说,这...
通过学习 Lucene,开发者不仅可以掌握全文检索的基本原理,还能了解如何设计高效的索引结构,以及如何根据特定需求定制搜索功能。例如,你可以自定义查询分析器、实现删除操作、扩展排序机制,以及利用 Lucene 的 ...
2. **索引构建**:Lucene将文档转换为倒排索引结构,这是一种高效的数据结构,允许快速查找包含特定词汇的文档。 3. **搜索查询**:用户可以通过QueryParser或直接构造Query对象来创建搜索请求。Lucene支持布尔查询...
**深入理解Lucene:系统结构解析** Lucene是一款开源的全文搜索引擎库,广泛应用于各种信息检索系统中。本文将从系统结构、源码组织、数据流及其相互关系等多个角度,帮助读者深入理解Lucene的核心机制。 ### **1....
### 一、Lucene基本概念 1. **索引**:Lucene首先对文本进行索引,将文本内容转换为一系列可搜索的结构。索引过程包括分词(Tokenization)、词干提取(Stemming)、停用词处理(Stop Word Removal)等步骤。 2. *...
这本书详细讲解了Lucene的各个方面,包括安装、基本用法、高级特性和实际应用案例。书中还包含了大量代码示例,帮助读者更好地理解和实践Lucene。 8. **压缩包中的资源** "lucene in action.pdf" 是《Lucene in ...