- 浏览: 208241 次
- 性别:
- 来自: 福建省
文章分类
最新评论
-
c929833623:
...
Mysql JDBC驱动源码分析(Statement,ResultSet的创建)四 -
pythonlord:
顶 很有帮助,感谢楼主,好人一生平安
Mysql JDBC驱动源码分析(加载驱动)一 -
kiaonly:
代码有错误,我戳。
解释器模式(Interpreter)---java与模式(例子) -
wyzxzws:
小鸟学习了!
JAVA编码问题记录 -
xiaotao.2010:
写的不错! 弱弱说一句 建议使用URL二次转码, 这样可以避免 ...
JAVA编码问题记录
创建索引时处理:
一,是否要被分词
1,Field.Index.ANALYZED:所传字段会被分词,会根据分词后进行查找
2,Field.Index.NOT_ANALYZED:所传字段不会被分词,会根据(原值)进行查找
3,Field.Index.NO:不参与分词,也不参与查找
二,是否被持久化保存在文件中
1,Field.Store.YES:索引时会被持久化,查找时可以查到相应的值
2,Field.Store.NO:索引时不被持久化.不会被存储
问题一:当同时配index_no store_no,时程序会报错误,,因为不存这样的情况,,,
例 子
一个Lucene Document添加以下Field
Field(path,not_analyzed,store.yes)
Field(content,analyzed,store.yes)
Field(name,not_analyzed,store.no)
1,当用path查找时,只能用(全路径查找)因为没有经过分词
2,当用content查找时,可以找到任意值
3,当用name查找时,只能用全名称查找,但是有参与索引,本身没有(持久化),故不能得到自己的值,但能得到同一个document上的值
-----------------------------------------------------------------------------
执行搜索时处理:
一,以怎样的方式进行搜索
1,BooleanClause.Occur.MUST:
2,BooleanClause.Occur.SHOULD:
3,BooleanClause.Occur.MUST_NOT:
以上主要对字段的合并查找,与sql中的含义一致 and or not
------------------------------------------------------------------------------
问题:
1,在对如一对多查询,对"多"的一方进行索引查询时,会关联出多个"一"上的信息,这时候需要用Lucene提供的一个过滤器DuplicateFilter(进行去重)
2,排序问题,Lucene提供了多种排序,不过对于时间排序,因为是根据字符串的compareTo类型比较,所以要是同一格式的才能排序
3,使用BooleanQuery进行查询时可以整合其他的查询使之达到如 (福建|上海)+上海 这种类型的查询组合查找
4,MultiFieldQueryParser.parser()进行查找时,只会对空格 加号等特殊字符串处理,如"调拨单 人员"会查出
调拨单 或者 人员的信息,,查不出调拨的相应信息,故对他进行了分词,并用IKAnalyzer进行了停词处理
//分词处理 IKSegmentation ikSegmentation = new IKSegmentation( new StringReader(queryValue), true); StringBuffer segmentCombine = new StringBuffer(); segmentCombine.append("\"" + queryValue + "\""); segmentCombine.append(" "); for (Lexeme lexeme = null; (lexeme = ikSegmentation.next()) != null;) { segmentCombine.append(lexeme.getLexemeText()); segmentCombine.append(" "); } queryValue = segmentCombine.toString(); Query q2 = MultiFieldQueryParser.parse(Version.LUCENE_30, queryValue, indexFields, clauses, getAnalyzer()); ((BooleanQuery) query).add(q2, BooleanClause.Occur.MUST);
5,返回高度且相关字符串的大小可用
SimpleHTMLFormatter
ighlighter.setTextFragmenter(new SimpleFragmenter(n));
6,lucene中设置返回的默认条数为100(可设置),对于分页没有中间查找,只有自己取出相要的条数再进行相应的运算.
7,在查询时出现"open too many files "error,是因为没有关闭Search,但是项目中已经关闭该Search,
原因:
当NIOFSDirectory不是作为参数传给IndexSearch时,indexSearch.close()并没有真正意义上的关闭,因为,他是交给IndexReader的,所以自己要search.getIndexReader().close()
8,当进行查询时,Lucene会把相应的索引全部载入内存,如果索引太大,耗费的内存不够用,可设置Search为单例不关闭
9,相似度问题(各个属性设置 参考文档)重写Similarity类
10,去重问题,Lucene本身提供了一个DuplicateFilter去重设置,不过这个Filter有一个问题,并不能满足需求
如:
主表 id:aa-xx-yy title:表单问题
从表 id:aa pid:aa-xx-yy content:你好
id: bb pid:aa-xx-yy content:谢谢
当在DuplicateFilter中设置pid去重时,默认是取最后一条,把第一条过滤掉,也就是你查"你好"时,关联不到主表的"表单问题",查"谢谢"就可以,...
解决:根据(FilteredQuery)重写一个这个类中的一个方法(在上传文件中)----不可用,,还未找到解决方案
11,在使用IKQueryParser时,进行对中文分词,出现问题如
“调拨功能”时,只会出现同时含有“调拨”,“功能”的记录,不会出现单独的如“调拨” 或者“功能”的记录
第4点有说过,查看了这个类的原码,是ik中全部采用了MUST的形式,,,---修改IKQueryParser
添加自己相要的实现类如下:
=-----------------------------------------------------------------上传不上来直接复制代码
12,实现高级搜索
高级搜索的处理主要对数字(如价格)与时间的处理,lucene提供了NumericRangeQuery与TermRangeQuery进行分别处理,不过对数字处理还得对索引进行特殊处理
13,实现排序功能
lucene中提供了排序的 sort = new Sort(sortFields.toArray(sortArray));功能,但是对一个排序正确,当加了如大小与时间排序时,,结果并不正确
14,显示高亮问题
在用搜索时,组合起来的query进行高亮处理时,字段设置为检索不分词时,没有高亮标记,,,
处理方法,,用客户端所传的值,设置一个专门为高亮应用的query,这个query的条件是最宽松的,都是分诩过的
/** * */ package com.fdauto.bws.business.module.lucene; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.BooleanClause.Occur; import org.wltea.analyzer.IKSegmentation; import org.wltea.analyzer.Lexeme; /** * IK查询分析器 * 实现了对分词歧义结果的非冲突排列组合 * 有效的优化对歧义关键词的搜索命中 * 针对IK Analyzer V3的优化实现 * * */ public final class BWSQueryParser { //查询关键字解析缓存线程本地变量 private static ThreadLocal<Map<String , TokenBranch>> keywordCacheThreadLocal = new ThreadLocal<Map<String , TokenBranch>>(); //是否采用最大词长分词 private static boolean isMaxWordLength = false; /** * 设置分词策略 * isMaxWordLength = true 采用最大词长分词 * @param isMaxWordLength */ //public static void setMaxWordLength(boolean isMaxWordLength) { //BWSQueryParser.isMaxWordLength = isMaxWordLength ; //} /** * 优化query队列 * 减少Query表达式的嵌套 * @param queries * @return */ private static Query optimizeQueries(List<Query> queries,boolean exactMatch){ //生成当前branch 的完整query if(queries.size() == 0){ return null; }else if(queries.size() == 1){ return queries.get(0); }else{ BooleanQuery mustQueries = new BooleanQuery(); if(exactMatch){ for(Query q : queries){ mustQueries.add(q, Occur.MUST); } }else{ for(Query q : queries){ mustQueries.add(q, Occur.SHOULD); } } return mustQueries; } } /** * 获取线程本地的解析缓存 * @return */ private static Map<String , TokenBranch> getTheadLocalCache(){ Map<String , TokenBranch> keywordCache = keywordCacheThreadLocal.get(); if(keywordCache == null){ keywordCache = new HashMap<String , TokenBranch>(4); keywordCacheThreadLocal.set(keywordCache); } return keywordCache; } /** * 缓存解析结果的博弈树 * @param query * @return */ private static TokenBranch getCachedTokenBranch(String query){ Map<String , TokenBranch> keywordCache = getTheadLocalCache(); return keywordCache.get(query); } /** * 缓存解析结果的博弈树 * @param query * @return */ private static void cachedTokenBranch(String query , TokenBranch tb){ Map<String , TokenBranch> keywordCache = getTheadLocalCache(); keywordCache.put(query, tb); } /** * 单连续字窜(不带空格符)单Field查询分析 * @param field * @param query * @return * @throws IOException */ private static Query _parse(String field , String query,boolean exactMatch) throws IOException{ if(field == null){ throw new IllegalArgumentException("parameter \"field\" is null"); } if(query == null || "".equals(query.trim())){ return new TermQuery(new Term(field)); } //从缓存中取出已经解析的query生产的TokenBranch TokenBranch root = getCachedTokenBranch(query); if(root != null){ return optimizeQueries(root.toQueries(field,exactMatch),exactMatch); }else{ //System.out.println(System.currentTimeMillis()); root = new TokenBranch(null); if(!query.startsWith("\"")&&!query.endsWith("\"")){ //对查询条件q进行分词 StringReader input = new StringReader(query.trim()); IKSegmentation ikSeg = new IKSegmentation(input , isMaxWordLength); for(Lexeme lexeme = ikSeg.next() ; lexeme != null ; lexeme = ikSeg.next()){ //处理词元分支 root.accept(lexeme); } }else{ //当有一个词加了引号之后,不分词(当传"调拨单"时,分词后变成"调拨单" 调拨 单 这样的话 在记录中恰好有"调拨单"比"调拨"的比重更大) //参考相似度中coord()当有匹配的最多时,权重最大 String[] querys=query.replace("\"", "").split("-"); for(String queryValue:querys){ Lexeme lexeme=new Lexeme(0,0,queryValue.length(),0); lexeme.setLexemeText(queryValue); root.accept(lexeme); } if(query.length()!=1){ String queryTemp=query.replaceAll("-", ""); Lexeme lexeme=new Lexeme(0,0,queryTemp.length(),0); lexeme.setLexemeText(queryTemp); root.accept(lexeme); } } //缓存解析结果的博弈树 cachedTokenBranch(query , root); return optimizeQueries(root.toQueries(field,exactMatch), exactMatch); } } /** * 单条件,单Field查询分析 * @param field -- Document field name * @param query -- keyword * @return Query 查询逻辑对象 * @throws IOException */ public static Query parse(String field , String query,boolean exactMatch) throws IOException{ if(field == null){ throw new IllegalArgumentException("parameter \"field\" is null"); } String[] qParts = query.split("\\s"); if(qParts.length > 1){ BooleanQuery resultQuery = new BooleanQuery(); for(String q : qParts){ //过滤掉由于连续空格造成的空字串 if("".equals(q)){ continue; } Query partQuery = _parse(field , q,exactMatch); if(partQuery != null && (!(partQuery instanceof BooleanQuery) || ((BooleanQuery)partQuery).getClauses().length>0)){ if(exactMatch) resultQuery.add(partQuery, Occur.MUST); else resultQuery.add(partQuery, Occur.SHOULD); } } return resultQuery; }else{ return _parse(field , query,exactMatch); } } /** * 多Field,单条件,多Occur查询分析 * @param fields -- Document fields name * @param query -- keyword * @param flags -- BooleanClause * @return Query 查询逻辑对象 * @throws IOException */ public static Query parseMultiField(String[] fields , String query , BooleanClause.Occur[] flags,boolean exactMatch) throws IOException{ if(fields == null){ throw new IllegalArgumentException("parameter \"fields\" is null"); } if(flags == null){ throw new IllegalArgumentException("parameter \"flags\" is null"); } if (flags.length != fields.length){ throw new IllegalArgumentException("flags.length != fields.length"); } BooleanQuery resultQuery = new BooleanQuery(); for(int i = 0; i < fields.length; i++){ if(fields[i] != null){ Query partQuery = parse(fields[i] , query,exactMatch); if(partQuery != null && (!(partQuery instanceof BooleanQuery) || ((BooleanQuery)partQuery).getClauses().length>0)){ resultQuery.add(partQuery, flags[i]); } } } return resultQuery; } /** * 多Field,多条件,多Occur查询分析 * @param fields * @param queries * @param flags * @return Query 查询逻辑对象 * @throws IOException */ public static Query parseMultiField(String[] fields , String[] queries , BooleanClause.Occur[] flags,boolean exactMatch) throws IOException{ if(fields == null){ throw new IllegalArgumentException("parameter \"fields\" is null"); } if(queries == null){ throw new IllegalArgumentException("parameter \"queries\" is null"); } if(flags == null){ throw new IllegalArgumentException("parameter \"flags\" is null"); } if (!(queries.length == fields.length && queries.length == flags.length)){ throw new IllegalArgumentException("queries, fields, and flags array have have different length"); } BooleanQuery resultQuery = new BooleanQuery(); for(int i = 0; i < fields.length; i++){ if(fields[i] != null){ Query partQuery = parse(fields[i] , queries[i], exactMatch); if(partQuery != null && (!(partQuery instanceof BooleanQuery) || ((BooleanQuery)partQuery).getClauses().length>0)){ resultQuery.add(partQuery, flags[i]); } } } return resultQuery; } /** * 词元分支 * 当分词出现歧义时,采用词元分支容纳不同的歧义组合 * */ private static class TokenBranch{ private static final int REFUSED = -1; private static final int ACCEPTED = 0; private static final int TONEXT = 1; //词元分支左边界 private int leftBorder; //词元分支右边界 private int rightBorder; //当前分支主词元 private Lexeme lexeme; //当前分支可并入的词元分支 private List<TokenBranch> acceptedBranchs; //当前分支的后一个相邻分支 private TokenBranch nextBranch; TokenBranch(Lexeme lexeme){ if(lexeme != null){ this.lexeme = lexeme; //初始化branch的左右边界 this.leftBorder = lexeme.getBeginPosition(); this.rightBorder = lexeme.getEndPosition(); } } public int getLeftBorder() { return leftBorder; } public int getRightBorder() { return rightBorder; } public Lexeme getLexeme() { return lexeme; } public List<TokenBranch> getAcceptedBranchs() { return acceptedBranchs; } public TokenBranch getNextBranch() { return nextBranch; } public int hashCode(){ if(this.lexeme == null){ return 0; }else{ return this.lexeme.hashCode() * 37; } } public boolean equals(Object o){ if(o == null){ return false; } if(this == o){ return true; } if(o instanceof TokenBranch){ TokenBranch other = (TokenBranch)o; if(this.lexeme == null || other.getLexeme() == null){ return false; }else{ return this.lexeme.equals(other.getLexeme()); } }else{ return false; } } /** * 组合词元分支 * @param _lexeme * @return 返回当前branch能否接收词元对象 */ boolean accept(Lexeme _lexeme){ /* * 检查新的lexeme 对当前的branch 的可接受类型 * acceptType : REFUSED 不能接受 * acceptType : ACCEPTED 接受 * acceptType : TONEXT 由相邻分支接受 */ int acceptType = checkAccept(_lexeme); switch(acceptType){ case REFUSED: // REFUSE 情况 return false; case ACCEPTED : if(acceptedBranchs == null){ //当前branch没有子branch,则添加到当前branch下 acceptedBranchs = new ArrayList<TokenBranch>(2); acceptedBranchs.add(new TokenBranch(_lexeme)); }else{ boolean acceptedByChild = false; //当前branch拥有子branch,则优先由子branch接纳 for(TokenBranch childBranch : acceptedBranchs){ acceptedByChild = childBranch.accept(_lexeme) || acceptedByChild; } //如果所有的子branch不能接纳,则由当前branch接纳 if(!acceptedByChild){ acceptedBranchs.add(new TokenBranch(_lexeme)); } } //设置branch的最大右边界 if(_lexeme.getEndPosition() > this.rightBorder){ this.rightBorder = _lexeme.getEndPosition(); } break; case TONEXT : //把lexeme放入当前branch的相邻分支 if(this.nextBranch == null){ //如果还没有相邻分支,则建立一个不交叠的分支 this.nextBranch = new TokenBranch(null); } this.nextBranch.accept(_lexeme); break; } return true; } /** * 将分支数据转成Query逻辑 * @return */ List<Query> toQueries(String fieldName,boolean exactMatch){ List<Query> queries = new ArrayList<Query>(1); //生成当前branch 的query if(lexeme != null){ queries.add(new TermQuery(new Term(fieldName , lexeme.getLexemeText()))); } //生成child branch 的query if(acceptedBranchs != null && acceptedBranchs.size() > 0){ if(acceptedBranchs.size() == 1){ Query onlyOneQuery = optimizeQueries(acceptedBranchs.get(0).toQueries(fieldName,exactMatch),exactMatch); if(onlyOneQuery != null){ queries.add(onlyOneQuery); } }else{ BooleanQuery orQuery = new BooleanQuery(); for(TokenBranch childBranch : acceptedBranchs){ Query childQuery = optimizeQueries(childBranch.toQueries(fieldName,exactMatch),exactMatch); if(childQuery != null){ orQuery.add(childQuery, Occur.SHOULD); } } if(orQuery.getClauses().length > 0){ queries.add(orQuery); } } } //生成nextBranch的query if(nextBranch != null){ queries.addAll(nextBranch.toQueries(fieldName,exactMatch)); } return queries; } /** * 判断指定的lexeme能否被当前的branch接受 * @param lexeme * @return 返回接受的形式 */ private int checkAccept(Lexeme _lexeme){ int acceptType = 0; if(_lexeme == null){ throw new IllegalArgumentException("parameter:lexeme is null"); } if(null == this.lexeme){//当前的branch是一个不交叠(ROOT)的分支 if(this.rightBorder > 0 //说明当前branch内至少有一个lexeme && _lexeme.getBeginPosition() >= this.rightBorder){ //_lexeme 与 当前的branch不相交 acceptType = TONEXT; }else{ acceptType = ACCEPTED; } }else{//当前的branch是一个有交叠的分支 if(_lexeme.getBeginPosition() < this.lexeme.getBeginPosition()){ //_lexeme 的位置比 this.lexeme还靠前(这种情况不应该发生) acceptType = REFUSED; }else if(_lexeme.getBeginPosition() >= this.lexeme.getBeginPosition() && _lexeme.getBeginPosition() < this.lexeme.getEndPosition()){ // _lexeme 与 this.lexeme相交 acceptType = REFUSED; }else if(_lexeme.getBeginPosition() >= this.lexeme.getEndPosition() && _lexeme.getBeginPosition() < this.rightBorder){ //_lexeme 与 this.lexeme 不相交, 但_lexeme 与 当前的branch相交 acceptType = ACCEPTED; }else{//_lexeme.getBeginPosition() >= this.rightBorder //_lexeme 与 当前的branch不相交 acceptType= TONEXT; } } return acceptType; } } }
package com.fdauto.doc; import org.apache.lucene.search.Similarity; public class MySimilarity extends Similarity { /** * 当查找词组时,命中率高的权重高 * 如:调拨 功能 同时出现的会更高 */ @Override public float coord(int overlap, int maxOverlap) { // TODO Auto-generated method stub return 1.0f; } /** * 在创建索引时,如Term="调拨" * 他在多个文档中,按理讲,应该跨越多文档权重越低 * */ @Override public float idf(int docFreq, int numDocs) { // TODO Auto-generated method stub return 1.0f; } /** * 这是对文档长度设置权重,长度越短,权重越高 * */ @Override public float lengthNorm(String fieldName, int numTokens) { // TODO Auto-generated method stub return 1.0f; } /** * 这是跟查询有关系的 */ @Override public float queryNorm(float sumOfSquaredWeights) { // TODO Auto-generated method stub return 1.0f; } /** * 这是在查找时,如调拨功能 * "调拨功能"比"调拨我们的功能" 越近的分数越高 * */ @Override public float sloppyFreq(int distance) { // TODO Auto-generated method stub return 1.0f / (distance + 1); } /** * 在一篇文档中出现的term越多权重发挥高 */ @Override public float tf(float freq) { // TODO Auto-generated method stub return 1.0f; } } /** * * score(q,d) = (6)coord(q,d) · (3)queryNorm(q) · ∑( (4)tf(t in d) · (5)idf(t)2 · t.getBoost() · (1)norm(t,d) ) t in q norm(t,d) = doc.getBoost() · (2)lengthNorm(field) · ∏f.getBoost() field f in d named as t 下面逐个进行解释: * */
Lucene 中wiki内容非常全面,可作为参考http://wiki.apache.org/lucene-java/LuceneFAQ#Why_am_I_getting_an_IOException_that_says_.22Too_many_open_files.22.3F
如何加快搜索速度:http://wiki.apache.org/lucene-java/ImproveSearchingSpeed
如何提高索引:http://wiki.apache.org/lucene-java/ImproveIndexingSpeed
发表评论
-
Solr研究
2012-03-26 10:14 2329一,概述 17173搜索是一套对站内各个系统的信 ... -
Lucene---全文检索(处理一对多去重问题 )
2011-01-13 16:15 5909在处理如"问答"功能时,以答进行搜索,这时假就会出现去重问题- ... -
Lucene---全文检索(文档pdf/txt/office/html)
2010-11-01 11:08 3090一,最近做了一些使用lucene对文档的一些搜索 主要使用 ... -
Lucene---全文检索(数据库)
2010-08-31 10:01 2848一,对Lucene的知识进行介绍http://lym6520. ...
相关推荐
《最新全文检索 Lucene-5.2.1 入门经典实例》 Lucene是一个开源的全文检索库,由Apache软件基金会开发,广泛应用于各种信息检索系统。在5.2.1版本中,Lucene提供了更为高效和强大的搜索功能,为开发者提供了构建...
Apache Lucene,作为开源的全文检索库,是Java开发人员进行高效信息检索的重要工具。这个压缩包文件包含了Lucene从2.9.4版本到3.4.0版本的核心组件,让我们一起探讨这些版本中的关键变化和核心知识点。 1. **Lucene...
Lucene是一个高性能、全文本搜索库,它为开发者提供了索引和搜索文本的工具。在2.4.1这个版本中,Lucene已经包含了对中文分词的支持,可以与各种分词器如jieba、IK、HanLP等配合使用,实现更精准的中文搜索。Je-...
Apache Lucene是一个开源全文搜索引擎库,由Java编写,被广泛应用于各种信息检索系统中。在本文中,我们将深入探讨其核心库——lucene-core-2.9.2.jar,以及与之相关的lucene-1.4.3.jar.license.txt文件。 一、...
在信息技术领域,搜索引擎的构建是至关重要的一环,而Lucene作为一个开源全文检索库,为开发者提供了强大的文本搜索功能。这里我们主要聚焦于Lucene 3.0.2版本,通过分析其核心组件和示例演示,来深入探讨这个版本的...
作为Java实现的全文检索引擎,Lucene提供了一套高度可扩展的API,支持索引和搜索大量文本数据。在“lucene-core-2.4.0.jar”这个版本中,Lucene已经相当成熟,可以满足各种复杂的搜索需求。 二、核心组件 1. 文档...
Lucene 广泛应用于内容管理系统、企业级搜索引擎、网站的站内搜索、数据分析平台等场景,为用户提供高效、准确的全文检索体验。 ### 6. 结合源码和工具学习 了解了 Lucene 的基础知识后,可以通过阅读源码来深入...
在信息技术领域,搜索引擎是至关重要的工具,而Lucene作为开源全文检索库,为开发者提供了强大的搜索功能。本文将深入探讨Lucene-Analyzers-3.3.0版本,解析其jar包与源码,帮助读者掌握这一核心组件的工作原理和...
Lucene 是一个开源的全文检索库,由Apache软件基金会维护,它为开发人员提供了高级文本搜索功能。在Java环境中,Lucene是构建搜索引擎的核心工具,它提供了高效的索引和查询机制,支持多种复杂的搜索语法。这里提到...
在IT领域,Lucene是一个非常重要的开源全文搜索引擎库,它为开发者提供了强大的文本分析、索引和搜索功能。这里我们关注的是Lucene的4.4.0版本,通过解压"lucene-codecs-4.4.0.zip",我们可以深入了解其内部机制和...
Lucene是一个高性能、全功能的全文搜索引擎库,它提供了一套完整的搜索解决方案,包括索引、查询解析、排序等。`lucene-core-2.4.1.jar`是Lucene的核心库,包含了Lucene的基础组件和API,如文档处理、索引操作、查询...
Lucene是一个开源的全文检索库,由Apache软件基金会开发,它提供了强大的文本搜索功能,被广泛应用于各种信息检索系统中。本文将围绕“lucene-2.9.2.jar”这个版本,结合源码,探讨其在中文分词和TF-IDF搜索引擎中的...
Lucene是一个开源全文检索库,由Apache软件基金会开发并维护。它为Java开发者提供了一种高级文本搜索功能,使得在应用程序中实现复杂、高效的搜索引擎成为可能。标题中的“lucene-2.4.0jar包”指的是Lucene的2.4.0...
4. **使用场景**: Lucene广泛应用于网站搜索、企业内部信息检索、日志分析、邮件搜索等多个领域。通过集成Lucene,开发者可以快速地实现高效、准确的全文本搜索功能。 5. **开发实践**: 在实际开发中,除了直接使用...
总结来说,"je-analysis-1.5.3"和"lucene-core-2.9.2"这两个jar包分别提供了文本分析和全文检索的功能,它们的结合使用可以构建强大的文本处理和搜索解决方案。理解并熟练运用这些工具,对于提升Java应用程序的数据...
在信息技术领域,搜索引擎是至关重要的工具,而Apache Lucene作为一款高性能、全文本搜索库,为开发者提供了强大的搜索引擎功能。本文将深入探讨Lucene的一个特殊模块——Memory索引,以“lucene-memory-3.0.1.jar”...
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎...
Lucene,作为一个开源全文检索库,以其高效、灵活的特点在信息检索领域广泛应用。在处理搜索结果时,为了提升用户体验,通常会采用高亮显示搜索关键词的功能。在`lucene-highlighter-2.2.0-src.zip`这个压缩包中,...
Lucene,这个由Apache软件基金会维护的开源全文检索库,是Java开发者构建高性能、可扩展的信息检索应用的重要工具。4.0.0版本的发布,为开发者提供了更强大的功能和优化的性能。本篇文章将围绕"lucene-4.0.0-src.zip...
**Lucene** 是一个开源的全文检索库,由Apache软件基金会开发并维护。它提供了高度可定制的搜索功能,被广泛应用于各种类型的搜索引擎和信息检索系统。Lucene 4.2.1是这个库的一个版本,它包含了源代码,允许开发者...