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

Lucene学习笔记

阅读更多
Lucene 学习笔记
一、环境
需要导入 lucene.jar 包(在 lucene.apache.org 下载)
二、基本概念
1 Lucene 的工作 流程:
(1)  使用 IndexWriter ,在指定的目录建立索引的文件
  (2) 
将需要检索的数据转换位 Document Filed 对象,然后 将 Document IndexWriter 添加倒索引的文件中
   (3) 
处理索引信息,关闭 IndexWriter
   (4) 
创建搜索的 Query
   (5) 
IndexSearcher
2 Lucene 的字段 类型
Lucene 有四种不同的字段类型: Keyword UnIndexed UnStored Text ,用于指定建立最佳索引。
?        Keyword
字段是指不需要分析 器 解析但需要被编入索引并保存到索引中的部分。 JavaSourceCodeIndexer 类使用该字段来保存导入类的声明。
?        UnIndexed
字段是既不被分 析也不被索引,但是要被逐字逐句的将其值保存到索引中。由于我们一般要存储文件的位置但又很少用文件名作为关键字来搜索,所以用该字段来索引 Java 文件名。
?        UnStored
字段和 UnIndexed 字段相反。该类型的 Field 要被分析并编入索引,但其值不会被保存到索引中。由于存储方法的全部源代码需要大量的空间。所以用 UnStored 字段 来存储被索引的方法源代码。可以直接从 Java 源文件中取出方法的源代码,这样作可以控制我们的索引的大小。
?        Text
字段在索引过程中是要被分析、索引并保存的。类名是作为 Text 字段来保存。下表展示了 JavaSourceCodeIndexer 类使用 Field 字段的一般情况。
 
3 基本概念(与传统表的对比):
Lucene
传统 表
说明
IndexWriter
table
 
Document
一条记录
 
Field
每个字段
分为可被索引的,可切分的,不可被切分的,不可被索引 的几种组合类型
Hits
RecoreSet
结果集
 
IndexWriter 提供了一些参数可供设置,列表如下
 
属性
默认值
说明
mergeFactor
org.apache.lucene.mergeFactor
10
控制 index 的大小和频率 , 两个作用
1. 一个段有多少 document
2. 多少个段合成一个大段
maxMergeDocs
org.apache.lucene.maxMergeDocs
Integer.MAX_VALUE
限制一个段中的 document 数目
minMergeDocs
org.apache.lucene.minMergeDocs
10
缓存在内存中的 document 数目,超过他以后会写入到磁盘
maxFieldLength
 
1000
一个 Field 中最大 Term 数目,超过部分忽略,不会 index field 中,所以自然 也就搜索不到
这些参数的的详细说明比较复杂: mergeFactor 有双重作用
(1) 设置每 mergeFactor document 写入 一个段,比如每 10 document 写入一个段
(2) 设置每 mergeFacotr 个 小段合并到一个大段,比如 10 document 的时候合并为 1 小段,以后有 10 个小段以后合并到一个大段,有 10 个大段以后再合并,实际的 document 数目会 是 mergeFactor 的指数
简单的来说 mergeFactor 越大,系统会用更多的内存,更少磁盘处理,如果要打批量的作 index ,那么把 mergeFactor 设 置大没错, mergeFactor 小了以后, index 数目也会增多, searhing 的效率会降低, 但是 mergeFactor 增 大一点一点,内存消耗会增大很多 ( 指数关系 ), 所以要留意不要” out of memory”
maxMergeDocs 设 置小,可以强制让达到一定数量的 document 写为一个段,这样可以抵消部分 mergeFactor 的作用 .
minMergeDocs
相当于设置一个小的 cache, 第一个这个数目的 document 会留在内存里面,不写入磁盘。这些参数同样是没有最佳值的, 必须根据实际情况一点点调整。
maxFieldLength
可以在任何时刻设置, 设置后,接下来的 index Field 会按照新的 length 截取,之前已经 index 的部分不会改变。可以设置为 Integer.MAX_VALUE
 
4 几种查询方式       
查询方式
说明
TermQuery
条件查询
例如: TermQuery tquery=new TermQuery(new Term("name","jerry"));
name: 字段名
jerry: 要搜索的字符串
MultiTermQuery
多个字段进行同一关键字的查询
Query query= null;
Query =MultiFieldQueryParser.parse(" ",new String[] {"title","content"},analyzer);
Searcher searcher=new IndexSearcher(indexFilePath);
 Hits hits=searcher.search(query);
BooleanQuery
例如: BooleanQuery bquery=new BooleanQuery();
 bquery.add(query,true,false);
   bquery.add(mquery,true,false);
   bquery.add(tquery,true,false);
   Searcher searcher=new IndexSearcher(indexFilePath);
    Hits hits=searcher.search(bquery);
WildcardQuery
语义查询(通配符查询)
例: Query query= new WildcardQuery(new Term("sender","*davy*"));
PhraseQuery
短语查询
PrefixQuery
前缀查询
PhrasePrefixQuery
短语前缀查询
FuzzyQuery
模糊查询
RangeQuery
范围查询
SpanQuery
范围查询
在全文检索时建议大家先采用语义时的搜索,先搜索出有意义的内容,之后再进行模 糊之类的搜索
(1) 联合两个索引查询,已解决:
IndexSearcher[] searchers = new IndexSearcher[2]; 
  
searchers[0] = new IndexSearcher(m_indexpath);
searchers[1] = new IndexSearcher(m_outindexpath);

MultiSearcher multiSearcher = new MultiSearcher(searchers);

(2)
还有个进行多条件搜索 and or 的操作————
MultiFieldQueryParser
建议重新封装
MultiFieldQueryParser.Parser(p[],d[],f[],analyer)  
or and 操作合一
或者
BooleanQuery m_BooleanQuery = new BooleanQuery();
Query query = QueryParser.Parse(m_SearchText, "INSTRUMENT_NAME", analyzer);
Query query2 = QueryParser.Parse(m_SearchText2, "INSTRUMENT_NAME2", analyzer);
m_BooleanQuery.Add(query, true, false);
m_BooleanQuery.Add(query2, true, false);
(3) 复合查询(多种查询条件的综合查询)
Query query=MultiFieldQueryParser.parse(" 索引 ”,new String[] {"title","content"},analyzer);
Searcher searcher=new IndexSearcher(indexFilePath);
Hits hits=searcher.search(query);
for (int i = 0; i < hits.length(); i++)  {
            System.out.println(hits.doc(i).get("name"));
}
 
5. 为查询优化索引 (index)
Indexwriter.optimize() 方法可以为查询优化索引( index ),之前提到的参数调优是为 indexing 过程 本身优化,而这里是为查询优化,优化主要是减少 index 文件数,这样让查询的时候少打开文件,优化过程中, lucene 会拷贝旧的 index 再合并,合 并完成以后删除旧的 index ,所以在此期间,磁盘占用增加, IO 符合也会增加,在优化完成瞬间,磁盘占用会是优化前的 2 , optimize 过程 中可以同时作 search
 
 
 
4.org.apache.lucene.document.Field
        
即上文所说的“字段”,它是 Document 的片段 section
        Field 的构造函数:
       Field(String name, String string, boolean store, boolean index, boolean token)
        Indexed :如果字段是 Indexed 的,表示这个字段是可检索的。
        Stored :如果字段是 Stored 的,表示这个字段的值可以从检索结果中得到。
        Tokenized :如果一个字段是 Tokenized 的,表示它是有经过 Analyzer 转变后成为一个 tokens 序列,在这个转变过程 tokenization 中,  Analyzer 提取出需要进行索引的文本,而剔除一些冗余的词句(例如: a the,they 等, 详见  org.apache.lucene.analysis.StopAnalyzer.ENGLISH_STOP_WORDS  org.apache.lucene.analysis.standard.StandardAnalyzer(String[] stopWords) API )。 Token 是索引时候的 .
 
类型
Analyzed
Indexed
Stored
说明
Field.Keyword(String,String/Date)
N
Y
Y
这个 Field 用来储存会直 接用来检索的比如 ( 编号 , 姓名 , 日期等 )
Field.UnIndexed(String,String)
N
N
Y
不会用来检索的信息 , 但是检索后需要显示的 , 比如 , 硬件序列号 , 文档的 url 地址
Field.UnStored(String,String)
Y
Y
N
大段文本内容 , 会用 来检索 , 但是检索后不需要从 index 中取内容 , 可以 根据 url load 真实的内容
Field.Text(String,String)
Y
Y
Y
检索 , 获取都需要的内容 , 直接放 index , 不过这样会增大 index
Field.Text(String,Reader)
Y
Y
N
如果是一个 Reader, lucene 猜测内容比较多 , 会采用 Unstored 的策略 .
 
 
5.Lucene  的检索结果排序
        Lucene 的排序主要是对 org.apache.lucene.search.Sort 的使用。 Sort 可以直接根据字段 Field 生成,也可以根据标准的 SortField 生成,但是作为 Sort 的字段,必须符合以下的条件:唯一值以及 Indexed 。可以对 Integers, Floats, Strings 三种类型排序。
        
对整数型的 ID 检索结果排序只要进行以下的简单操作:
Sort sort = new Sort("id");
 Hits hits = searcher.search(query, sort);
用户还可以根据自己定义更加复杂的排序,详细请参 考 API
 
6 分析器
Lucene 使用分析器来处理被索引的文本。在将其存入索引之前,分析器用于将文本标记化、摘录有关的单词、丢弃 共有的单词、处理派生词(把派生词还原到词根形式,意思是把 bowling bowler bowls 还原为 bowl )和完成其它要做的处理。 Lucene 提供的通用分析器是:
        SimpleAnalyzer
:用字符串标记一组单词并且转化为小写字母。
        StandardAnalyzer
:用字符串标记一组单词,可识别缩写词、 email 地址、主机名 称等等。并丢弃基于英语的 stop words (a, an, the, to) 等、处理派生词。
   ChineseAnalyzer.class,它是一个单 字分析法,它把句子中的词全部分成一个一个的字符,以单个字为单位存储。
CJKAnalyzer .class, 它是双字分析法,它把中文以双字为单位拆分得到结果,从而建立词条。当然这些得到的双字词中会有很多不符合中文语义单位的双字被送进索引。
 
十、需 要注意的问题:
1 .IndexWriter 在添加新的 document 后,需要重新建立 Index ,则需要调用 writer.optimize(); 方法
2. Lucene
没有 update 索引的方法,需要删除后重新建立,参考 remove 方法
3 .
IndexReader 删 除 Document 后,需要重新用 IndexWriter 进行整理,否则无法在进行搜索(不知道是不是我设置问题)
4.Lucene 先在内存中进行索引操作,并根据一定的批量进行文件的写入。这个批次的间隔越大,文件的写入次数越少, 但占用内存会很多。反之占用内存少,但文件 IO 操作频繁,索引速度会很慢。在 IndexWriter 中有一个 MERGE_FACTOR 参 数可以帮助你在构造索引器后根据应用环境的情况充分利用内存减少文件的操作。根据我的使用经验:缺省 Indexer 是每 20 条记录索引后写入 一次,每将 MERGE_FACTOR 增加 50 倍,索引速度可以提高 1 倍左右。
5 . 并发操作 Lucene
(1) 所有只读操作都可以并发
(2) index 被修改期间,所有只读操作都可以并发
(3) index 修改操作不能并发,一个 index 只能被一个线程占用
(4)ndex 的优化,合并,添加都是修改操作
(5) 但需要注意的是 , 在创建搜索的时候用 :
searcher = new IndexSearcher(IndexReader.open("E:\\lucene\\test4\\index"));
searcher.close();
这时候是不能关闭 searcher .
如果想让 searcher 能关 闭 , 就不要用 IndexReader :
  searcher = new IndexSearcher("E:\\lucene\\test4\\index");
6 Locking 机制
 lucence 内部使用文件来 locking 默认的 locking 文件放 在 java.io.tmpdir, 可以通过 -Dorg.apache.lucene.lockDir=xxx 指定新的 dir ,有 write.lock commit.lock 两个文件, lock 文件用来防止并 行操作 index ,如果并行操作, lucene 会抛出异常,可以通过设置 -DdisableLuceneLocks=true 来禁止 locking ,这样做一般来说很危险,除非你有操作系统或者物理级别的只读保证,比如把 index 文件刻盘到 CDROM 上。
十一、 2.0 中新增特性
1. 新增类: org.apache.lucene.index.IndexModifier ,它合并了     IndexWriter IndexReader , 好处是我们可以增加和删除文档的时候不同担心 synchronisation/locking 的问题了。
2. 增加对 contrib/highlighter NullFragmenter , 这对全文本加亮很有用。
3. 增加了新类 MatchAllDocsQuery 用来匹配所有文档。
4.. 增加 ParallelReader ,这个一种 IndexReader 他合并多个单独的索引到一个单独的虚拟索引上。
 5. 增加 Hits.iterator() 方法和相应的 HitIterator Hit 对象。
他提供了对 Hits 对象标准的 java.util.Iterator 叠代操作。
每个 iterator's next() 方法返回一个   Hit 对象。  
 6. term vectors 中增加了 位置和偏移信 息。 (Grant Ingersoll & Christoph) 
 7. 增加了一个新的 DateTools 。 允许用户格式化日期到一种更可读的格式,以便于更好的适应索引。 DateTools 不像 DateFields 类,它允许日期指定到 1970 年以前,但必 须使用指定的日期格式。这样,在 RangeQuerys 中使用就更加有效率了。
8. 增加了对压缩字段存储的支持。 (patch #29370)
  
 
 
 
 
实例:
1. 判断索引文件是否存在 :
/**
     *
检查索引是否存在 .
     * @param indexDir
     * @return
     */
    public static boolean indexExist(String indexDir)
    {
        return IndexReader.indexExists(indexDir);
    }
 private IndexWriter getWriter(String indexFilePath) throws Exception {
        boolean append=true;
        File file=new File(indexFilePath+File.separator+"segments");
        if(file.exists())
            append=false; 
        return new IndexWriter(indexFilePath,analyzer,append);
    }
 
2. 删除索引
/**
     *
删除索引 .
     * @param aTerm
索引删除条件
     * @param indexDir
索引目录
     */
    public static void deleteIndex(Term aTerm, String indexDir)
    {
        List aList = new ArrayList();
        aList.add(aTerm);
        deleteIndex(aList, indexDir);
    }
    /**
     *
删除索引 .
     * @param aTerm
索引删除条件 .
     * @param indexDir
索引目录      * 
     */
    public static void deleteIndex(List terms, String indexDir)
    {
        if (null == terms) {
            return;
        }
       
        if(!indexExist(indexDir)) { return; }
        IndexReader reader = null;
        try {
            reader = IndexReader.open(indexDir);
            for (int i = 0; i < terms.size(); i++){
                Term aTerm = (Term) terms.get(i);
                if (null != aTerm){
                    reader.delete(aTerm);
                }
            }
        } catch (IOException e){
            LogMan.warn("Error in Delete Index", e);
        } finally {
            try{
                if (null != reader){
                    reader.close();
                }
            }catch (IOException e){
                LogMan.warn("Close reader Error");
            }
        }
    } 
 删除索引需要一个条 件,类似数据库中的字段条件,例如删除一条新闻的代码如下:
     public static void deleteNewsInfoIndex(int nid)
     {
         Term aTerm = new Term("nid", String.valueOf(nid));
         deleteIndex(aTerm,indexDir);
     }   

注:本文有些知识是1.4下的,如果你用的是2.0可能这些例子不能很好的运行。不过我觉得看了以上的东西,再结合一些例子就能对lucene有一 定的理解了,最起码可以开始干活了。在2.0版本中创建索引和进行多种搜索的例子我会陆继写出来与大家一起学习。

分享到:
评论

相关推荐

    lucene学习笔记

    标题:Lucene学习笔记 描述:Lucene学习笔记,Lucene入门必备材料 知识点: 一、Lucene概述与文档管理策略 Lucene是一款高性能、全功能的文本搜索引擎库,广泛应用于文档检索、全文搜索等场景。为了提升搜索效率...

    Lucene 学习笔记 1

    **Lucene 学习笔记 1** Lucene 是一个全文搜索引擎库,由 Apache 软件基金会开发。它提供了一个可扩展的、高性能的搜索框架,使得开发者能够在其应用程序中集成高级的搜索功能。本篇学习笔记将深入探讨 Lucene 的...

    Lucene学习笔记.doc

    【Lucene学习笔记】 Lucene是一个高性能、全文检索的开源库,完全用Java编写,能够帮助开发者在应用程序中实现复杂的搜索引擎功能。它提供了强大的索引和搜索机制,使得从大量文本数据中快速找到相关信息变得简单。...

    Lucene学习笔记(一)Lucene入门实例

    NULL 博文链接:https://kylinsoong.iteye.com/blog/719415

    【大搜集:lucene学习资料】---<下载不扣分,回帖加1分,欢迎下载,童叟无欺>

    lucene学习笔记 1 .txt lucene学习笔记 2.txt lucene学习笔记 3 .txt lucene入门实战.txt Lucene 的学习 .txt Lucene-2.0学习文档 .txt Lucene入门与使用 .txt lucene性能.txt 大富翁全文索引和查询的例子...

    lucene学习资料

    10. **lucene学习笔记 3 .txt** 这是作者的学习笔记,可能包含了个人理解和使用Lucene过程中遇到的问题及解决方案,提供了不同角度的见解和实践经验。 通过这些文档,你可以系统地学习和掌握Lucene的各个方面,从...

    Lucene 3.6 学习笔记

    【Lucene 3.6 学习笔记】 Lucene 是一个高性能、全文本搜索库,广泛应用于各种搜索引擎的开发。本文将深入探讨Lucene 3.6版本中的关键概念、功能以及实现方法。 ### 第一章 Lucene 基础 #### 1.1 索引部分的核心...

    Lucene开发指南

    Lucene学习笔记(二)可能涉及索引构建过程,讲解了如何使用Document对象存储文档内容,Field对象定义字段属性,以及如何使用IndexWriter进行索引更新和优化。 笔记(三)和(四)可能深入到查询解析和执行。查询解析器...

    lucene3.5学习笔记

    ### Lucene 3.5 学习笔记 #### 一、Lucene 3.5 基本概念 ##### 1.1 Lucene 概述 **1.1.1 IndexWriter** `IndexWriter` 是 Lucene 中的核心类之一,用于创建或更新索引。它提供了添加文档、删除文档、优化索引等...

    基于lucene和nutch的开源搜索引擎资料集合

    Lucene学习笔记.doc nutch_tutorial.pdf nutch二次开发总结.txt nutch入门.pdf nutch入门学习.pdf Nutch全文搜索学习笔记.doc Yahoo的Hadoop教程.doc [硕士论文]_基于Lucene的Web搜索引擎实现.pdf [硕士论文]_基于...

    lunece 学习笔记实用知识库分享知识分享

    Lucene 学习笔记是指如何学习和使用 Lucene。我们可以通过学习 Lucene 的使用和实现来掌握 Lucene。 Solr 学习笔记 Solr 学习笔记是指如何学习和使用 Solr。我们可以通过学习 Solr 的使用和实现来掌握 Solr。 ...

    【分享:lucene学习资料】---<下载不扣分,回帖加1分,欢迎下载,童叟无欺>

    1&gt; lucene学习笔记 2&gt; 全文检索的实现机制 【1】lucene学习笔记的目录如下 1. 概述 3 2. lucene 的包结构 3 3. 索引文件格式 3 4. lucene中主要的类 4 4.1. Document文档类 4 4.1.1. 常用方法 4 4.1.2. 示例 4 4.2...

Global site tag (gtag.js) - Google Analytics