`
wu_quanyin
  • 浏览: 208273 次
  • 性别: Icon_minigender_1
  • 来自: 福建省
社区版块
存档分类
最新评论

Lucene---全文检索(问题分析)

阅读更多

 

创建索引时处理:

 

一,是否要被分词

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

 

 

1
0
分享到:
评论

相关推荐

    最新全文检索 lucene-5.2.1 入门经典实例

    《最新全文检索 Lucene-5.2.1 入门经典实例》 Lucene是一个开源的全文检索库,由Apache软件基金会开发,广泛应用于各种信息检索系统。在5.2.1版本中,Lucene提供了更为高效和强大的搜索功能,为开发者提供了构建...

    lucene-core-2.9.4,lucene-core-3.0.2,lucene-core-3.0.3,lucene-core-3.4.0

    Apache Lucene,作为开源的全文检索库,是Java开发人员进行高效信息检索的重要工具。这个压缩包文件包含了Lucene从2.9.4版本到3.4.0版本的核心组件,让我们一起探讨这些版本中的关键变化和核心知识点。 1. **Lucene...

    je-analysis-1.5.3、lucene-core-2.4.1分词组件

    Lucene是一个高性能、全文本搜索库,它为开发者提供了索引和搜索文本的工具。在2.4.1这个版本中,Lucene已经包含了对中文分词的支持,可以与各种分词器如jieba、IK、HanLP等配合使用,实现更精准的中文搜索。Je-...

    lucene-core-2.9.2.jar

    Apache Lucene是一个开源全文搜索引擎库,由Java编写,被广泛应用于各种信息检索系统中。在本文中,我们将深入探讨其核心库——lucene-core-2.9.2.jar,以及与之相关的lucene-1.4.3.jar.license.txt文件。 一、...

    lucene-core-3.0.2.jar,lucene-demos-3.0.2.jar

    在信息技术领域,搜索引擎的构建是至关重要的一环,而Lucene作为一个开源全文检索库,为开发者提供了强大的文本搜索功能。这里我们主要聚焦于Lucene 3.0.2版本,通过分析其核心组件和示例演示,来深入探讨这个版本的...

    lucene-core-2.4.0.jar

    作为Java实现的全文检索引擎,Lucene提供了一套高度可扩展的API,支持索引和搜索大量文本数据。在“lucene-core-2.4.0.jar”这个版本中,Lucene已经相当成熟,可以满足各种复杂的搜索需求。 二、核心组件 1. 文档...

    Lucene---全文检索(文档pdf/txt/office/html)

    Lucene 广泛应用于内容管理系统、企业级搜索引擎、网站的站内搜索、数据分析平台等场景,为用户提供高效、准确的全文检索体验。 ### 6. 结合源码和工具学习 了解了 Lucene 的基础知识后,可以通过阅读源码来深入...

    lucene-analyzers-3.3.0 jar包和源码

    在信息技术领域,搜索引擎是至关重要的工具,而Lucene作为开源全文检索库,为开发者提供了强大的搜索功能。本文将深入探讨Lucene-Analyzers-3.3.0版本,解析其jar包与源码,帮助读者掌握这一核心组件的工作原理和...

    lucene-core-2.3.0 lucene-core2.4.0以及极易分词器 jar包

    Lucene 是一个开源的全文检索库,由Apache软件基金会维护,它为开发人员提供了高级文本搜索功能。在Java环境中,Lucene是构建搜索引擎的核心工具,它提供了高效的索引和查询机制,支持多种复杂的搜索语法。这里提到...

    lucene-codecs-4.4.0.zip

    在IT领域,Lucene是一个非常重要的开源全文搜索引擎库,它为开发者提供了强大的文本分析、索引和搜索功能。这里我们关注的是Lucene的4.4.0版本,通过解压"lucene-codecs-4.4.0.zip",我们可以深入了解其内部机制和...

    MMAnalyzer 分词必导入jar包(lucene-core-2.4.1.jar je-analysis-1.5.3.jar)

    Lucene是一个高性能、全功能的全文搜索引擎库,它提供了一套完整的搜索解决方案,包括索引、查询解析、排序等。`lucene-core-2.4.1.jar`是Lucene的核心库,包含了Lucene的基础组件和API,如文档处理、索引操作、查询...

    lucene-2.9.2.jar包+源码

    Lucene是一个开源的全文检索库,由Apache软件基金会开发,它提供了强大的文本搜索功能,被广泛应用于各种信息检索系统中。本文将围绕“lucene-2.9.2.jar”这个版本,结合源码,探讨其在中文分词和TF-IDF搜索引擎中的...

    最全的lucene-2.4.0jar包

    Lucene是一个开源全文检索库,由Apache软件基金会开发并维护。它为Java开发者提供了一种高级文本搜索功能,使得在应用程序中实现复杂、高效的搜索引擎成为可能。标题中的“lucene-2.4.0jar包”指的是Lucene的2.4.0...

    Lucene-core-2.0.0

    4. **使用场景**: Lucene广泛应用于网站搜索、企业内部信息检索、日志分析、邮件搜索等多个领域。通过集成Lucene,开发者可以快速地实现高效、准确的全文本搜索功能。 5. **开发实践**: 在实际开发中,除了直接使用...

    je-analysis-1.5.3;lucene-core-2.9.2

    总结来说,"je-analysis-1.5.3"和"lucene-core-2.9.2"这两个jar包分别提供了文本分析和全文检索的功能,它们的结合使用可以构建强大的文本处理和搜索解决方案。理解并熟练运用这些工具,对于提升Java应用程序的数据...

    lucene-memory-3.0.1.jar

    在信息技术领域,搜索引擎是至关重要的工具,而Apache Lucene作为一款高性能、全文本搜索库,为开发者提供了强大的搜索引擎功能。本文将深入探讨Lucene的一个特殊模块——Memory索引,以“lucene-memory-3.0.1.jar”...

    lucene-3.5.0.zip

    Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎...

    lucene-highlighter-2.2.0-src.zip

    Lucene,作为一个开源全文检索库,以其高效、灵活的特点在信息检索领域广泛应用。在处理搜索结果时,为了提升用户体验,通常会采用高亮显示搜索关键词的功能。在`lucene-highlighter-2.2.0-src.zip`这个压缩包中,...

    lucene-4.0.0-src.zip 【Lucene 4.0.0源码包src , source】

    Lucene,这个由Apache软件基金会维护的开源全文检索库,是Java开发者构建高性能、可扩展的信息检索应用的重要工具。4.0.0版本的发布,为开发者提供了更强大的功能和优化的性能。本篇文章将围绕"lucene-4.0.0-src.zip...

    lucene-4.2.1-src.tgz

    **Lucene** 是一个开源的全文检索库,由Apache软件基金会开发并维护。它提供了高度可定制的搜索功能,被广泛应用于各种类型的搜索引擎和信息检索系统。Lucene 4.2.1是这个库的一个版本,它包含了源代码,允许开发者...

Global site tag (gtag.js) - Google Analytics