- 浏览: 269705 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (195)
- EXT学习 (2)
- hibernate (3)
- drools (1)
- TDD测试驱动开发 (3)
- js (7)
- php (3)
- appfuse (2)
- css (5)
- 站长文库 (15)
- flex (6)
- lucene (43)
- 业务建模 (1)
- Pentaho Report Designer (1)
- 代码质量 (10)
- webservice (2)
- 美工 (3)
- dot net (7)
- 人生 (5)
- 方法论 (3)
- html (4)
- 需求管理 (2)
- 资源分享 (2)
- JAVA (6)
- IDE--intelij文章收集 (5)
- 爬虫学习 (1)
- air (2)
- json转换 (1)
- Linux (2)
- C C++ (1)
- mysql word export 导出 (1)
- avast windows server 2003 (3)
- Linux yum (1)
- flash as3 actionscript 错误码 参考 (1)
- actionscript (1)
- 快速开发 (2)
- ios (0)
- erLang (1)
- 手机开发 (1)
- mysql (1)
- 苹果 MacOs (1)
最新评论
-
cuidongdong1234:
有没有源码分析呀?
初步了解jackson -
ieblaze:
您好!我测试了下 ,启动不成警告: Could not get ...
Embed Tomcat 开发,调试项目 -
Feegle7:
楼主,你这个ppt太花了,估计,大家根本没心思看内容了
drools的学习总结 -
filix:
zhoche2008 写道本来写得挺好的。非要搞一些PPT动画 ...
drools的学习总结 -
zhoche2008:
这PPT真耗资源,服了
drools的学习总结
研究SegmentInfo类的实现。
虽然在阅读代码的时候,是一件很枯燥的事情,尤其是当代码非常地长,这使得我们感觉这是一种压力,但是如果把代码当成是一种乐趣的时候,你会发现代码是那样的富有感情色彩。呵呵。
SegmentInfo类在Lucene 2.0.0版本的时候,定义非常简单,就定义了一个构造函数,如下所示:
package org.apache.lucene.index;
import org.apache.lucene.store.Directory;
final class SegmentInfo {
public String name; // unique name in dir
public int docCount; // number of docs in seg
public Directory dir; // where segment resides
public SegmentInfo(String name, int docCount, Directory dir) {
this.name = name;
this.docCount = docCount;
this.dir = dir;
}
}
但是,到了2.2.0版本的时候,SegmentInfo类的定义就相当复杂了。
因为2.2.0版本是在之前的版本的基础上进行开发的,所以涉及到一些概念,尤其是文件格式,提前了解一下这些概念对于理解SegmentInfo类有很大帮助。
*************************************************************************************
Normalization Factors(标准化因子):可以参考http://lucene.apache.org/java/2_2_0/fileformats.html#Normalization%20Factors
【在2.1之前的版本,存在下面的一些格式的文件】
在每个Document逻辑文件中,对于一个被索引的Field,都对应着一个norm文件,该norm文件的一个字节与Document有非常密切的关系。
这个.f[0-9]*文件,是为每个Document设置的,当Document中的一个Field被命中的时候,.f[0-9]*文件包含的就是:一个字节编码值乘以排序分值。
一个单独的norm文件的创建,仅仅是在一个复合segments文件被创建的时候才存在。即:一个单独的norm文件的存在是依赖于复合segments的,如果复合segments文件不存在,就不会生成一个单独的norm文件。
【在2.1版本及其之后的版本,存在下面的一些格式的文件】
只使用一个.nrm文件,该文件包含了所有的标准化因子。所有的.nrm文件都包含NormsHeader和<Norms> NumFieldsWithNorms 这两部分。
其中:
NormsHeader包含4个字节,前三个字节为“N”、“R”、“M”,最后一个字节指定了FORMAT版本号,当前因为是2.2.0版本,版本号为-1,可以在SegmentInfos类的定义开始部分看到:
public static final int FORMAT = -1;
<Norms>对应这一个<Byte>,而NumFieldsWithNorms 对应于一个Segments的大小,即SegSize。
一个.nrm文件的每个字节都编码成一个浮点值,该字节的前3bits(即0-2)表示尾数,后5bits(即3-7)表示指数。
当一个已经存在segments文件的标准化因子值(即norm的value)被修改,同时一个单独的norm文件被创建;当Field N被修改,同时一个.sN文件被创建,这个.sN文件用来保存该Field的标准化因子值(即norm的value)。
当适当的时候,一个单独的norm文件的创建,可以是为了一个复合segments文件,也可以不是复合segments文件。
*************************************************************************************
在2.2.0版本中,SegmentInfo类实现的源代码如下所示:
package org.apache.lucene.index;
mport org.apache.lucene.store.Directory;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.store.IndexInput;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
final class SegmentInfo {
static final int NO = -1; // 如果不存在标准化因子.nrm文件,和.del文件
static final int YES = 1; // 如果存在标准化因子.nrm文件,和.del文件
static final int CHECK_DIR = 0; // 需要检查该索引目录,是否存在标准化因子.nrm文件,和.del文件
static final int WITHOUT_GEN = 0; // 一个索引文件的名称中,没有gen值,即:根本没有对其进行过添加(或者是追加、删除)操作
public String name; // 在索引目录中的唯一索引文件名
public int docCount; // 在索引段中Document的数量
public Directory dir; // 一个索引段文件所属于的索引目录为dir
private boolean preLockless; // 为true,当一个索引段文件在无锁提交之前被写入
private long delGen; // 当前版本(generation)删除时的gen的值为delGen(即segments_delGen.del)
private long[] normGen; // 每个Field对应的norm文件的gen
private byte isCompoundFile; // 如果为NO,则表示不用检查;如果为YES表示检查是否存在2.1版本之前的扩展名为.cfs和.nrm的文件
private boolean hasSingleNormFile; //如果一个segments存在一个单独的norm文件。在当前版本中,false表示一个segments是由DocumentWriter生成的,true表示为最新创建的合并的索引段文件(包括复合segments文件和非复合segments文件)
private List files; // 在当前索引目录中,当前索引段用到的文件在缓存中的列表
// 构造一个SegmentInfo对象(根据指定的参数:索引段名称、索引文件中Document的数量、指定的所以目录)
public SegmentInfo(String name, int docCount, Directory dir) {
this.name = name;
this.docCount = docCount;
this.dir = dir;
delGen = NO; // 初始化一个SegmentInfo的时候,指定存在标准化因子.nrm文件,和.del文件
isCompoundFile = CHECK_DIR; // 检查该索引目录dir,看是否存在一些2.1版本之前的扩展名为.cfs和.nrm的文件
preLockless = true; // 为true,当一个索引段文件在无锁提交之前被写入
hasSingleNormFile = false; // 指定一个segments是由DocumentWriter生成的
}
// 构造一个SegmentInfo对象
public SegmentInfo(String name, int docCount, Directory dir, boolean isCompoundFile, boolean hasSingleNormFile) {
this(name, docCount, dir);
this.isCompoundFile = (byte) (isCompoundFile ? YES : NO);
this.hasSingleNormFile = hasSingleNormFile;
preLockless = false; // 为false,当一个索引段文件不是在无锁提交之前被写入
}
/**
* 根据指定的SegvmentInfo,拷贝它到我们当前的SegmentInfo实例中,其实就是重新构造一个SegmentInfo,重新构造的该SegmentInfo与指定的SegmentInfo src是相同的
*/
void reset(SegmentInfo src) {
files = null;
name = src.name;
docCount = src.docCount;
dir = src.dir;
preLockless = src.preLockless;
delGen = src.delGen;
if (src.normGen == null) { // 每个Field对应的norm文件的gen不存在(为null)
normGen = null;
} else {
normGen = new long[src.normGen.length];
// arraycopy的声明为:public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
System.arraycopy(src.normGen, 0, normGen, 0, src.normGen.length);
}
isCompoundFile = src.isCompoundFile;
hasSingleNormFile = src.hasSingleNormFile;
}
// 构造一个SegmentInfo对象,通过构造一个索引输入流对象IndexInput
SegmentInfo(Directory dir, int format, IndexInput input) throws IOException {
this.dir = dir;
name = input.readString();
docCount = input.readInt();
if (format <= SegmentInfos.FORMAT_LOCKLESS) {
delGen = input.readLong();
if (format <= SegmentInfos.FORMAT_SINGLE_NORM_FILE) {
hasSingleNormFile = (1 == input.readByte());
} else {
hasSingleNormFile = false;
}
int numNormGen = input.readInt();
if (numNormGen == NO) {
normGen = null;
} else {
normGen = new long[numNormGen];
for(int j=0;j<numNormGen;j++) {
normGen[j] = input.readLong();
}
}
isCompoundFile = input.readByte();
preLockless = (isCompoundFile == CHECK_DIR);
} else {
delGen = CHECK_DIR; // CHECK_DIR = 0
normGen = null;
isCompoundFile = CHECK_DIR;
preLockless = true; // 一个索引段文件在无锁提交之前被写入过
hasSingleNormFile = false; // 一个segments是由DocumentWriter生成的
}
}
// 为每个Field的norm文件设置gen值
void setNumFields(int numFields) {
if (normGen == null) {
// 如果是2.1版本之前的segment文件,或者该segment文件没有对应的norm文件,则normGen=null
normGen = new long[numFields];
if (preLockless) {
// 保持normGen[k]==CHECK_DIR (==0), 之后会为这些norm文件检查文件系统,因为它们是以前版本中无锁提交的
} else {
// 这是一个无锁提交写入的segment, 不存在单独的norm文件
for(int i=0;i<numFields;i++) {
normGen[i] = NO; // 对每个Field,设置norm文件的gen值为NO=-1
}
}
}
}
// 是否存在.del文件
boolean hasDeletions()
throws IOException {
// 如果delGen == NO==-1: 表示使用LOCKLESS模式,其中一些segment不存在.del文件
if (delGen == NO) {
return false;
} else if (delGen >= YES) { // YES的值为1,如果segment文件是无锁提交的,其中一些存在.del文件
return true;
} else {
return dir.fileExists(getDelFileName()); // getDelFileName()在后面定义了该方法,获取删除的该索引目录下的文件名
}
}
void advanceDelGen() {
// delGen 0 is reserved for pre-LOCKLESS format
if (delGen == NO) {
delGen = YES;
} else {
delGen++;
}
files = null;
}
// 设置delGen的值为NO,即-1
void clearDelGen() {
delGen = NO;
files = null;
}
public Object clone () { // SegmentInfo支持克隆
SegmentInfo si = new SegmentInfo(name, docCount, dir);
si.isCompoundFile = isCompoundFile;
si.delGen = delGen;
si.preLockless = preLockless;
si.hasSingleNormFile = hasSingleNormFile;
if (normGen != null) {
si.normGen = (long[]) normGen.clone();
}
return si;
}
String getDelFileName() { 获取删除的该索引目录下的文件名
if (delGen == NO) {
// 如果delGen==NO,则表示不删除
return null;
} else {
// 如果delGen是CHECK_DIR,,则它是以前的无锁提交格式
return IndexFileNames.fileNameFromGeneration(name, "." +IndexFileNames.DELETES_EXTENSION, delGen); // 即返回文件名为name_delGen.del,例如segments_5.del
}
}
/**
* 如果该索引段的这个Field作为separate norms文件(_<segment>_N.sX)进行存储
* fieldNumber是一个需要检查的field的索引
*/
boolean hasSeparateNorms(int fieldNumber)
throws IOException {
if ((normGen == null && preLockless) || (normGen != null && normGen[fieldNumber] == CHECK_DIR)) {
// Must fallback to directory file exists check:
String fileName = name + ".s" + fieldNumber;
return dir.fileExists(fileName);
} else if (normGen == null || normGen[fieldNumber] == NO) {
return false;
} else {
return true;
}
}
/**
* 返回true如果这个segments中的任何一个Field都存在一个单独的norm文件
*/
boolean hasSeparateNorms()
throws IOException {
if (normGen == null) { // 如果normGen = null
if (!preLockless) {
// 不存在norm文件,返回false
return false;
} else {
// segment使用pre-LOCKLESS模式保存,需要回退到最初的目录下,进行核查
String[] result = dir.list();
if (result == null) // 如果获取的文件列表为null
throw new IOException("cannot read directory " + dir + ": list() returned null");
// 否则,如果获取的文件列表不空
String pattern;
pattern = name + ".s"; // 设置文件名的匹配格式字符串,形如name.s的形式
int patternLength = pattern.length();
for(int i = 0; i < result.length; i++){ // 循环匹配
if(result[i].startsWith(pattern) && Character.isDigit(result[i].charAt(patternLength)))
return true;
}
return false;
}
} else { // 如果normGen != null
// 这个segment使用LOCKLESS模式保存
// 需要检查是否任何一个normGen都是 >= 1的
// (它们有一个单独的norm文件):
for(int i=0;i<normGen.length;i++) {
if (normGen[i] >= YES) { // YES=1
return true;
}
}
// 查找normGen == 0的,这些情况是re
// pre-LOCKLESS模式提交的,需要检查:
for(int i=0;i<normGen.length;i++) {
if (normGen[i] == CHECK_DIR) {
if (hasSeparateNorms(i)) {
return true;
}
}
}
}
return false;
}
/**
* 为每个Field的norm文件的gen,执行加1操作
* @param fieldIndex:指定的Field的norm文件需要被重写,fieldIndex即对应的norm文件的gen值
*/
void advanceNormGen(int fieldIndex) {
if (normGen[fieldIndex] == NO) {
normGen[fieldIndex] = YES;
} else {
normGen[fieldIndex]++;
}
files = null;
}
/**
* 获取Field的norm文件的文件名称;number是一个Field的索引值
*/
String getNormFileName(int number) throws IOException {
String prefix;
long gen;
if (normGen == null) {
gen = CHECK_DIR; // CHECK_DIR==0
} else {
gen = normGen[number]; // 根据Field的索引值获取它对应的norm文件的gen值,然后使用该gen值取得索引段文件的文件名
}
if (hasSeparateNorms(number)) {
// case 1: separate norm
prefix = ".s";
return IndexFileNames.fileNameFromGeneration(name, prefix + number, gen); // 使用gen值取得索引段文件的文件名,如果name=“segments”,number=7,gen=4,则返回的文件名为segments_4.s7
}
if (hasSingleNormFile) { // 如果存在一个单独的norm文件
// case 2: lockless (or nrm file exists) - single file for all norms
prefix = "." + IndexFileNames.NORMS_EXTENSION; // IndexFileNames.NORMS_EXTENSION=nrm
return IndexFileNames.fileNameFromGeneration(name, prefix, WITHOUT_GEN); // 如果name=“segments”,则返回的文件名为segments.nrm
}
// case 3: norm file for each field
prefix = ".f";
return IndexFileNames.fileNameFromGeneration(name, prefix + number, WITHOUT_GEN); // 如果name=“segments”,number=7,则返回的文件名为segments.f7
}
/**
*指定,是否segment文件作为复合文件存储()
*/
void setUseCompoundFile(boolean isCompoundFile) {
if (isCompoundFile) {
this.isCompoundFile = YES;
} else {
this.isCompoundFile = NO;
}
files = null;
}
/**
* 如果索引文件被作为复合文件存储,则返回true
*/
boolean getUseCompoundFile() throws IOException {
if (isCompoundFile == NO) {
return false;
} else if (isCompoundFile == YES) {
return true;
} else {
return dir.fileExists(name + "." + IndexFileNames.COMPOUND_FILE_EXTENSION);
}
}
/**
*保存segment的信息,其实就是输出(写入)到磁盘中的索引目录中
*/
void write(IndexOutput output)
throws IOException {
output.writeString(name);
output.writeInt(docCount);
output.writeLong(delGen);
output.writeByte((byte) (hasSingleNormFile ? 1:0));
if (normGen == null) {
output.writeInt(NO);
} else {
output.writeInt(normGen.length);
for(int j = 0; j < normGen.length; j++) {
output.writeLong(normGen[j]);
}
}
output.writeByte(isCompoundFile);
}
/*
* 返回所有的被当前SegmentInfo引用的所有的文件的列表,由于是在本地缓存中,你不应该设法去修改他们
*/
public List files() throws IOException {
if (files != null) {
return files;
}
files = new ArrayList();
boolean useCompoundFile = getUseCompoundFile();
if (useCompoundFile) {
files.add(name + "." + IndexFileNames.COMPOUND_FILE_EXTENSION); // IndexFileNames.COMPOUND_FILE_EXTENSION=csf
} else {
/* INDEX_EXTENSIONS_IN_COMPOUND_FILE定义了如下所示的复合文件扩展名:
static final String[] INDEX_EXTENSIONS_IN_COMPOUND_FILE = new String[] {
"fnm", "fdx", "fdt", "tii", "tis", "frq", "prx",
"tvx", "tvd", "tvf", "nrm"
};
*/
for (int i = 0; i < IndexFileNames.INDEX_EXTENSIONS_IN_COMPOUND_FILE.length; i++) {
String ext = IndexFileNames.INDEX_EXTENSIONS_IN_COMPOUND_FILE[i];
String fileName = name + "." + ext;
if (dir.fileExists(fileName)) {
files.add(fileName);
}
}
}
String delFileName = IndexFileNames.fileNameFromGeneration(name, "." + IndexFileNames.DELETES_EXTENSION, delGen); // IndexFileNames.DELETES_EXTENSION=del;如果name=“segments”,delGen=6,则返回的文件名为segments_6.del
if (delFileName != null && (delGen >= YES || dir.fileExists(delFileName))) {
files.add(delFileName);
}
// Careful logic for norms files
if (normGen != null) {
for(int i=0;i<normGen.length;i++) {
long gen = normGen[i];
if (gen >= YES) {
// Definitely a separate norm file, with generation:
files.add(IndexFileNames.fileNameFromGeneration(name, "." + IndexFileNames.SEPARATE_NORMS_EXTENSION + i, gen)); // IndexFileNames.SEPARATE_NORMS_EXTENSION=s;如果name=“segments”,gen=6,i=8,则返回的文件名为segments_6.s8
} else if (NO == gen) {
// No separate norms but maybe plain norms
// in the non compound file case:
if (!hasSingleNormFile && !useCompoundFile) {
String fileName = name + "." + IndexFileNames.PLAIN_NORMS_EXTENSION + i; // IndexFileNames.PLAIN_NORMS_EXTENSION=f;如果name=“segments”,gen=6,i=8,则返回的文件名为segments_6.f8
if (dir.fileExists(fileName)) {
files.add(fileName);
}
}
} else if (CHECK_DIR == gen) {
// 2.1版本之前:我们需要验证这些文件的存在性
String fileName = null;
if (useCompoundFile) {
fileName = name + "." + IndexFileNames.SEPARATE_NORMS_EXTENSION + i; // 若name="segments",i=X=8,则该类文件形如segments.s8
} else if (!hasSingleNormFile) {
fileName = name + "." + IndexFileNames.PLAIN_NORMS_EXTENSION + i; // 若name="segments",i=X=8,则该类文件形如segments.f8
}
if (fileName != null && dir.fileExists(fileName)) {
files.add(fileName);
}
}
}
} else if (preLockless || (!hasSingleNormFile && !useCompoundFile)) {
// 2.1版本之前的: 需要为我们当前的索引段扫描索引目录找到所有的匹配的_X.sN或_X.fN的文件
String prefix;
if (useCompoundFile)
prefix = name + "." + IndexFileNames.SEPARATE_NORMS_EXTENSION; // 若name="segments",则该类文件形如segments.s
else
prefix = name + "." + IndexFileNames.PLAIN_NORMS_EXTENSION; // 若name="segments",则该类文件形如segments.f
int prefixLength = prefix.length();
String[] allFiles = dir.list();
if (allFiles == null)
throw new IOException("cannot read directory " + dir + ": list() returned null");
for(int i=0;i<allFiles.length;i++) {
String fileName = allFiles[i];
if (fileName.length() > prefixLength && Character.isDigit(fileName.charAt(prefixLength)) && fileName.startsWith(prefix)) {
files.add(fileName);
}
}
}
return files;
}
}
通过SegmentInfo类的定义,总结一下:
1、主要针对2.1版本前后的不同形式的Segments进行处理,尤其是复合segments文件;
2、对每个Field的norm文件进行处理:设置该norm文件的gen;
3、使用write()方法,将一个处理过的Segments文件写入索引目录;
4、2.1版本以后,统一使用一个.nrm文件,该文件包含了所有的标准化因子,因为需要对2.1版本以前的版本进行支持,需要处理2.1版本之前的一些版本中,对标准化因子设置文件进行处理。
5、根据getNormFileName(int number)方法,可以总结出:
(1) 通过一个索引段文件的索引值number,可以得到它的norm文件的gen值,这个gen值其实就是这个segments的gen,即形如segments_N形式,N=gen。
(2) 2.1版本以后的,norm文件只使用一个.nrm扩展名的文件来代替以前的norm文件,则这个文件就是segments.nrm文件,并且对于同一个索引段,只有一个segments.nrm文件。
(3) 2.1版本以前的,norm文件的形式有:segments.fN、segments_N.sX两种。其中N是gen值,X是一个Field在Document中的索引值。
6、通过调用files()方法,可以获取索引目录下存在的不同扩展名的文件的一个列表,即该索引目录下的所有可能存在文件(通过文件扩展名区分),可以分出下面几组:
(1) 如果useCompoundFile=true,获取到扩展名为.cfs的复合文件;
(2) 如果useCompoundFile=false,获取到扩展名为如下的复合文件:
fnm、fdx、fdt、tii、tis、frq、prx、tvx、tvd、tvf、nrm;
(3) 如果是删除文件,获取到扩展名为.del的文件,若name="segments",delGen=6,则文件名形如segments_6.del;
(4) 如果normGen != null且normGen[i] >= YES=1,获取到扩展名为.sX的文件,若name="segments",gen=6,i=X=8,则该类文件形如segments_6.s8;
(5) 如果normGen != null且normGen[i] = NO=-1且hasSingleNormFile=false且useCompoundFile=false,获取到扩展名为.fX的文件,若name="segments",gen=6,i=X=8,则该类文件形如segments_6.f8;
(6) 如果normGen != null且normGen[i] = CHECK_DIR=0且useCompoundFile=true,获取到扩展名为.sX的文件,若name="segments",i=X=8,则该类文件形如segments.s8;
(7) 如果normGen != null且normGen[i] = CHECK_DIR=0且hasSingleNormFile=false且useCompoundFile=false,获取到扩展名为.fX的文件,若name="segments",i=X=8,则该类文件形如segments.f8;
(8) 如果normGen == null的时候,preLockless = true或(||)(hasSingleNormFile=false且useCompoundFile=false),这时若useCompoundFile=true,则获取到扩展名为.s的文件,若name="segments",则该类文件形如segments.s;
(9) 如果normGen == null的时候,preLockless = true或(||)(hasSingleNormFile=false且useCompoundFile=false),这时若useCompoundFile=false,则获取到扩展名为.f的文件,若name="segments",则该类文件形如segments.f;
发表评论
-
Lucene-2.2.0 源代码阅读学习(40)
2009-06-04 14:37 1199关于Lucene检索结果的排序问题。 已经知道,Luce ... -
Lucene-2.2.0 源代码阅读学习(39)
2009-06-04 14:35 888关于Lucene得分的计算。 在IndexSearche ... -
Lucene-2.2.0 源代码阅读学习(38)
2009-06-04 14:34 1481关于QueryParser。 QueryPars ... -
Lucene-2.2.0 源代码阅读学习(37)
2009-06-04 14:32 961关于MultiTermQuery查询。 ... -
Lucene-2.2.0 源代码阅读学习(36)
2009-06-04 14:23 1040关于MultiTermQuery查询。 ... -
Lucene-2.2.0 源代码阅读学习(35)
2009-06-04 14:22 750关于MultiPhraseQuery(多短语查询)。 Mul ... -
Lucene-2.2.0 源代码阅读学习(34)
2009-06-04 14:21 1109关于PhraseQuery。 PhraseQuery查询是将 ... -
Lucene-2.2.0 源代码阅读学习(33)
2009-06-04 14:20 800关于范围查询RangeQuery ... -
Lucene-2.2.0 源代码阅读学习(32)
2009-06-04 14:18 1112关于SpanQuery(跨度搜索),它是Query的子类,但是 ... -
Lucene-2.2.0 源代码阅读学习(31)
2009-06-04 14:15 1063关于前缀查询PrefixQuery(前缀查询)。 准备工作就 ... -
Lucene-2.2.0 源代码阅读学习(30)
2009-06-04 14:14 853关于Query的学习。 主要使用TermQuery和Bool ... -
Lucene-2.2.0 源代码阅读学习(29)
2009-06-04 14:12 1039关于IndexSearcher检索器。 ... -
Lucene-2.2.0 源代码阅读学习(28)
2009-06-04 14:09 928关于检索的核心IndexSearcher类。 IndexSe ... -
Lucene-2.2.0 源代码阅读学习(27)
2009-06-04 14:07 863关于Lucene的检索(IndexSearcher)的内容 ... -
Lucene-2.2.0 源代码阅读学习(26)
2009-06-04 14:06 1120如果在初始化一个IndexWr ... -
Lucene-2.2.0 源代码阅读学习(25)
2009-06-04 14:03 858复合索引文件格式(.cfs)是如何产生的?从这个问题出发,研究 ... -
Lucene-2.2.0 源代码阅读学习(24)
2009-06-04 13:58 940阅读了这么多代码, ... -
Lucene-2.2.0 源代码阅读学习(23)
2009-06-04 13:55 815通过对DocumentWriter类的writePosting ... -
Lucene-2.2.0 源代码阅读学习(22)
2009-06-04 13:54 864关于FieldInfos类和FieldInfo类。 Fi ... -
Lucene-2.2.0 源代码阅读学习(21)
2009-06-04 13:53 833回到IndexWriter索引器类 ...
相关推荐
lucene-analyzers-2.2.0.jarlucene-analyzers-2.2.0.jarlucene-analyzers-2.2.0.jarlucene-analyzers-2.2.0.jarlucene-analyzers-2.2.0.jarlucene-analyzers-2.2.0.jarlucene-analyzers-2.2.0.jarlucene-analyzers-...
标题中的"lucene-2.2.0zip"指的是Lucene的2.2.0版本,这是一个较早的版本,对于学习和理解Lucene的基础概念非常有帮助。 Lucene 2.2.0的主要特性包括: 1. **全文检索**:Lucene支持对文档内容进行全文检索,允许...
lucene-highlighter-2.2.0.jarlucene-highlighter-2.2.0.jarlucene-highlighter-2.2.0.jarlucene-highlighter-2.2.0.jarlucene-highlighter-2.2.0.jarlucene-highlighter-2.2.0.jarlucene-highlighter-2.2.0.jar
《Lucene-2.3.1 源代码阅读学习》 Lucene是Apache软件基金会的一个开放源码项目,它是一个高性能、全文本搜索库,为开发者提供了在Java应用程序中实现全文检索功能的基础架构。本篇文章将深入探讨Lucene 2.3.1版本...
《深入解析Lucene高亮显示源码:剖析`lucene-highlighter-2.2.0-src.zip`》 Lucene,作为一个开源全文检索库,以其高效、灵活的特点在信息检索领域广泛应用。在处理搜索结果时,为了提升用户体验,通常会采用高亮...
《深入剖析Lucene 2.2.0源代码》 Lucene是一款强大的开源全文搜索引擎库,由Apache软件基金会开发并维护。它为Java开发者提供了一种高性能、可扩展的文本检索核心工具。本文将深入探讨Lucene 2.2.0版本的源代码,...
在前面Lucene-2.2.0 源代码阅读学习(1)中,根据Lucene提供的一个Demo,详细分析研究一下索引器org.apache.lucene.index.IndexWriter类,看看它是如果定义的,掌握它建立索引的机制。 通过IndexWriter类的实现源代码...
赠送源代码:lucene-analyzers-smartcn-7.7.0-sources.jar; 赠送Maven依赖信息文件:lucene-analyzers-smartcn-7.7.0.pom; 包含翻译后的API文档:lucene-analyzers-smartcn-7.7.0-javadoc-API文档-中文(简体)版....
赠送源代码:lucene-core-7.7.0-sources.jar; 赠送Maven依赖信息文件:lucene-core-7.7.0.pom; 包含翻译后的API文档:lucene-core-7.7.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.lucene:lucene...
- 通过阅读源代码,可以理解Lucene的内部工作原理,如如何构建索引、执行查询等。 - 分析器部分的源码有助于了解文本预处理过程,包括分词、去除停用词等。 - 探究查询解析器的实现,掌握如何将自然语言转化为...
赠送源代码:lucene-analyzers-common-6.6.0-sources.jar; 赠送Maven依赖信息文件:lucene-analyzers-common-6.6.0.pom; 包含翻译后的API文档:lucene-analyzers-common-6.6.0-javadoc-API文档-中文(简体)版.zip;...
这是一个java开发用的.jar文件,用它和Lucene-core-2.0.0.jar可以实现搜索引擎
赠送源代码:lucene-core-7.2.1-sources.jar; 赠送Maven依赖信息文件:lucene-core-7.2.1.pom; 包含翻译后的API文档:lucene-core-7.2.1-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.lucene:lucene...
赠送源代码:lucene-suggest-6.6.0-sources.jar; 赠送Maven依赖信息文件:lucene-suggest-6.6.0.pom; 包含翻译后的API文档:lucene-suggest-6.6.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache....
赠送源代码:lucene-backward-codecs-7.3.1-sources.jar; 赠送Maven依赖信息文件:lucene-backward-codecs-7.3.1.pom; 包含翻译后的API文档:lucene-backward-codecs-7.3.1-javadoc-API文档-中文(简体)-英语-对照...
赠送源代码:lucene-core-6.6.0-sources.jar; 赠送Maven依赖信息文件:lucene-core-6.6.0.pom; 包含翻译后的API文档:lucene-core-6.6.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.lucene:lucene...
赠送源代码:lucene-spatial-extras-7.3.1-sources.jar; 赠送Maven依赖信息文件:lucene-spatial-extras-7.3.1.pom; 包含翻译后的API文档:lucene-spatial-extras-7.3.1-javadoc-API文档-中文(简体)-英语-对照版....
赠送源代码:lucene-memory-6.6.0-sources.jar; 赠送Maven依赖信息文件:lucene-memory-6.6.0.pom; 包含翻译后的API文档:lucene-memory-6.6.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.lucene:...
赠送源代码:lucene-suggest-7.7.0-sources.jar; 赠送Maven依赖信息文件:lucene-suggest-7.7.0.pom; 包含翻译后的API文档:lucene-suggest-7.7.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache....
赠送源代码:lucene-analyzers-smartcn-7.7.0-sources.jar; 赠送Maven依赖信息文件:lucene-analyzers-smartcn-7.7.0.pom; 包含翻译后的API文档:lucene-analyzers-smartcn-7.7.0-javadoc-API文档-中文(简体)-英语...