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版本中创建索引和进行多种搜索的例子我会陆继写出来与大家一起学习。

以下是对提供的参考资料的总结,按照要求结构化多个要点分条输出: 4G/5G无线网络优化与网规案例分析: NSA站点下终端掉4G问题:部分用户反馈NSA终端频繁掉4G,主要因终端主动发起SCGfail导致。分析显示,在信号较好的环境下,终端可能因节能、过热保护等原因主动释放连接。解决方案建议终端侧进行分析处理,尝试关闭节电开关等。 RSSI算法识别天馈遮挡:通过计算RSSI平均值及差值识别天馈遮挡,差值大于3dB则认定有遮挡。不同设备分组规则不同,如64T和32T。此方法可有效帮助现场人员识别因环境变化引起的网络问题。 5G 160M组网小区CA不生效:某5G站点开启100M+60M CA功能后,测试发现UE无法正常使用CA功能。问题原因在于CA频点集标识配置错误,修正后测试正常。 5G网络优化与策略: CCE映射方式优化:针对诺基亚站点覆盖农村区域,通过优化CCE资源映射方式(交织、非交织),提升RRC连接建立成功率和无线接通率。非交织方式相比交织方式有显著提升。 5G AAU两扇区组网:与三扇区组网相比,AAU两扇区组网在RSRP、SINR、下载速率和上传速率上表现不同,需根据具体场景选择适合的组网方式。 5G语音解决方案:包括沿用4G语音解决方案、EPS Fallback方案和VoNR方案。不同方案适用于不同的5G组网策略,如NSA和SA,并影响语音连续性和网络覆盖。 4G网络优化与资源利用: 4G室分设备利旧:面对4G网络投资压减与资源需求矛盾,提出利旧多维度调优策略,包括资源整合、统筹调配既有资源,以满足新增需求和提质增效。 宏站RRU设备1托N射灯:针对5G深度覆盖需求,研究使用宏站AAU结合1托N射灯方案,快速便捷地开通5G站点,提升深度覆盖能力。 基站与流程管理: 爱立信LTE基站邻区添加流程:未提供具体内容,但通常涉及邻区规划、参数配置、测试验证等步骤,以确保基站间顺畅切换和覆盖连续性。 网络规划与策略: 新高铁跨海大桥覆盖方案试点:虽未提供详细内容,但可推测涉及高铁跨海大桥区域的4G/5G网络覆盖规划,需考虑信号穿透、移动性管理、网络容量等因素。 总结: 提供的参考资料涵盖了4G/5G无线网络优化、网规案例分析、网络优化策略、资源利用、基站管理等多个方面。 通过具体案例分析,展示了无线网络优化中的常见问题及解决方案,如NSA终端掉4G、RSSI识别天馈遮挡、CA不生效等。 强调了5G网络优化与策略的重要性,包括CCE映射方式优化、5G语音解决方案、AAU扇区组网选择等。 提出了4G网络优化与资源利用的策略,如室分设备利旧、宏站RRU设备1托N射灯等。 基站与流程管理方面,提到了爱立信LTE基站邻区添加流程,但未给出具体细节。 新高铁跨海大桥覆盖方案试点展示了特殊场景下的网络规划需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值