#
final class SegmentInfos extends Vector
可以看出該類實(shí)際上是一個(gè)Vector 以及封裝了對(duì)該Vevtor的一些操作
實(shí)際上封裝的是對(duì)segments文件的一些讀寫操作
先來(lái)看下segments文件的格式
segments文件的格式:
int: =-1 文件是否是Lucene合法的文件格式正常情況下為 -1
long: 版本號(hào),每更新一次該文件將會(huì)將版本號(hào)加1
int: 用來(lái)命名新段
int: 段的數(shù)目
String + int 段的信息 String是段的名稱 int是段中所含的doc數(shù)目
String + int 同上
所以用Lucene的API,我們可以簡(jiǎn)單的打印出其segments的所有信息
try {
//DataInputStream fis = new DataInputStream(new FileInputStream("C:\\sf\\snow\\segments"));
FSDirectory dir=FSDirectory.getDirectory("C:/sf/snow", false);
InputStream input = dir.openFile("segments");
System.out.println("Format:"+input.readInt()); //得到文件標(biāo)志,是否為正常的segments文件
System.out.println("version:"+input.readLong()); //得到版本號(hào)
System.out.println("name:"+input.readInt()); //得到用來(lái)重命名新段的int,暫時(shí)不知道有什么用
int n=input.readInt(); //段的數(shù)目
System.out.println("SegmentNum:"+n);
for(int i=0;i<n;i++) { //用循環(huán)打印出所有段的信息 名稱和長(zhǎng)度
System.out.println("segment "+i+" - name:"+input.readString()+" num:"+input.readInt());
}
} catch (Exception e) {
}
當(dāng)然,該類提供了更為復(fù)雜的訪問(wèn)和更新segments文件的方法
final void read(Directory directory) 將所有的段信息保存在本vector中
final void write(Directory directory) 跟新該segment文件的內(nèi)容,主要是為了添加段,
主要是更新 版本號(hào) 段的數(shù)目,跟新完這些后即可往segment文件后添加新段的信息。
segment(段)的信息
該類比較簡(jiǎn)單,貼出其全部代碼
import org.apache.lucene.store.Directory;
final class SegmentInfo {
public String name; //在索引目錄中唯一的名稱
public int docCount; // 該段中doc的數(shù)目
public Directory dir; // 該段所存在的Dirrectory
public SegmentInfo(String name, int docCount, Directory dir) {
this.name = name;
this.docCount = docCount;
this.dir = dir;
}
}
該類是從RAMFile中讀數(shù)據(jù)用的
最重要的一個(gè)方法:
該方法存在著從RAMFile的多個(gè)byte[1024]中讀取數(shù)據(jù)的情況,所以應(yīng)該在循環(huán)中進(jìn)行處理
public void readInternal(byte[] dest, int destOffset, int len) {
int remainder = len;
int start = pointer;
while (remainder != 0) {
int bufferNumber = start/BUFFER_SIZE; // buffer的序號(hào)
int bufferOffset = start%BUFFER_SIZE; // buffer偏移量
int bytesInBuffer = BUFFER_SIZE - bufferOffset;// 在當(dāng)前buffer中剩下的字節(jié)數(shù)
//如果緩沖區(qū)中剩余的字節(jié)大于len,則讀出len長(zhǎng)度的字節(jié),如果不夠則讀出剩余的字節(jié)數(shù)
// bytesToCopy表示實(shí)際讀出的字節(jié)數(shù)
int bytesToCopy = bytesInBuffer >= remainder ? remainder : bytesInBuffer;
byte[] buffer = (byte[])file.buffers.elementAt(bufferNumber);
System.arraycopy(buffer, bufferOffset, dest, destOffset, bytesToCopy);
destOffset += bytesToCopy; //增加已經(jīng)復(fù)制的byte數(shù)據(jù)長(zhǎng)度 到 dest中的偏移量
start += bytesToCopy; //RAMFile文件指針,用來(lái)確定bufferNumber 和bytesInBuffer 相當(dāng)于內(nèi)存中的分頁(yè)
remainder -= bytesToCopy; //剩余的還未復(fù)制的字節(jié)數(shù)
}
pointer += len;//文件指針位置
}
這是OutputStream的一個(gè)子類,其輸出設(shè)備是內(nèi)存,準(zhǔn)確來(lái)說(shuō)是RAMFile,即將數(shù)據(jù)寫入到RAMFile的Vector中去。
該類有一個(gè)最重要的方法,現(xiàn)在把它整個(gè)貼出來(lái)
public void flushBuffer(byte[] src, int len) {
int bufferNumber = pointer/BUFFER_SIZE; //buffer序列,即當(dāng)前所寫B(tài)uffer在RAMFile中的Vector中的序列號(hào)
int bufferOffset = pointer%BUFFER_SIZE; //偏移量,即當(dāng)前所寫字節(jié)在當(dāng)前Buffer中的偏移量。
int bytesInBuffer = BUFFER_SIZE - bufferOffset; //當(dāng)前Buffer的剩余可寫字節(jié)數(shù)
//bytesToCopy是實(shí)際寫入的字節(jié)數(shù),如果當(dāng)前Bufer的剩余字節(jié)數(shù)大于需要寫的字節(jié)的總數(shù)則寫入所有字節(jié)
//否則,將當(dāng)前Buffer寫滿即可,剩余的字節(jié)將寫入下一個(gè)Buffer
int bytesToCopy = bytesInBuffer >= len ? len : bytesInBuffer;
if (bufferNumber == file.buffers.size())
file.buffers.addElement(new byte[BUFFER_SIZE]); //在RAMFile中添加新的byte[1024]元素
byte[] buffer = (byte[])file.buffers.elementAt(bufferNumber);
System.arraycopy(src, 0, buffer, bufferOffset, bytesToCopy);
if (bytesToCopy < len) { // not all in one buffer,
int srcOffset = bytesToCopy;
bytesToCopy = len - bytesToCopy; // remaining bytes 剩余的未寫入的字節(jié)數(shù)
bufferNumber++; //將buffer數(shù)增加1
if (bufferNumber == file.buffers.size())
file.buffers.addElement(new byte[BUFFER_SIZE]);
buffer = (byte[])file.buffers.elementAt(bufferNumber); //剩余字節(jié)寫入下一個(gè)Buffer
System.arraycopy(src, srcOffset, buffer, 0, bytesToCopy);
}
pointer += len;
if (pointer > file.length)
file.length = pointer; //移位文件指針 在原有的基礎(chǔ)上加上實(shí)際寫入的字節(jié)總數(shù)
file.lastModified = System.currentTimeMillis(); //修改文件的最后修改時(shí)間為當(dāng)前時(shí)間
}
從指定的字節(jié)數(shù)組復(fù)制指定長(zhǎng)度的字節(jié)到RAMFile中去。由于RAMFile中Vector的元素是byte[1024]所以可能存在做一次該操作
要操作兩個(gè)Vector元素的情況。即先將當(dāng)前byte[1024]數(shù)組填滿,再新建一個(gè)元素裝載剩余的字節(jié)。
另外還有一個(gè)writeTo(OutputStream out)方法,將RAMFile中的數(shù)據(jù)輸出到另一個(gè)輸出流
這個(gè)類比較簡(jiǎn)單
import java.util.Vector;
class RAMFile {
Vector buffers = new Vector();
long length;
long lastModified = System.currentTimeMillis();
}
可以理解為一個(gè)存儲(chǔ)在內(nèi)存中的文件,buffers是存儲(chǔ)數(shù)據(jù)的容器,length是容器中數(shù)據(jù)的總的字節(jié)數(shù)
lastModified 是最后修改時(shí)間。
在實(shí)際使用過(guò)程中容器buffers存放的對(duì)象是一個(gè)byte[1024]數(shù)組。
OutputStream
這是一個(gè)Abstract類,是Lucene自己的一個(gè)文件輸出流的基類
BUFFER_SIZE = 1024 緩沖區(qū) 大小為 1024bit
bufferStart = 0 文件位置指針
bufferPosition = 0 內(nèi)存緩沖區(qū)指針
public final void writeByte(byte b) throws IOException {
if (bufferPosition >= BUFFER_SIZE)
flush();
buffer[bufferPosition++] = b;
}
幾乎所有的寫入函數(shù)都要調(diào)用這個(gè)函數(shù),如果緩沖區(qū)的當(dāng)前容量已經(jīng)等于他的最大容量,則將緩沖區(qū)中的數(shù)據(jù)寫入文件。
public final void writeBytes(byte[] b, int length) throws IOException
批量寫byte進(jìn)入內(nèi)存緩沖
public final void writeInt(int i) throws IOException
寫入整形數(shù)據(jù)
public final void writeLong(long i) throws IOException
寫入長(zhǎng)整型數(shù)據(jù),即結(jié)合移位運(yùn)算調(diào)用兩次writeInt(int i)
另外,最值得注意的是在該類中有兩個(gè)最特殊的函數(shù)
writeVInt(int i) / writeVLong(long i),
先說(shuō)
writeVInt(int i ) {
while ((i & ~0x7F) != 0) {
writeByte((byte)((i & 0x7f) | 0x80));
i >>>= 7;
}
writeByte((byte)i);
}
~0x7F==~(0111 1111)==(1000 0000)==0x80
((i & ~0x7F) != 0) 這一句判斷i是否大于0x80,如果不是則說(shuō)明該int只有一個(gè)字節(jié)的有效數(shù)據(jù),其他字節(jié)都是0,直接轉(zhuǎn)化為Byte寫入。
如果大于0x80則
(i & 0x7f) | 0x80
i&0x7f 只對(duì)后7位進(jìn)行處理,|0x80將第8位置1,與前面的7個(gè)bit構(gòu)成一個(gè)字節(jié),置1的原因是說(shuō)明該字節(jié)并不是一個(gè)完整的整形數(shù),需要與其他的字節(jié)合起來(lái)才能構(gòu)成一個(gè)整形數(shù)字。
這個(gè)算法相當(dāng)于將一個(gè)32bit的整形數(shù)字按照每7位編碼成一個(gè)字節(jié)進(jìn)行存儲(chǔ),將按照整形數(shù)的大小存儲(chǔ)1-5個(gè)字節(jié)。
writeVLong(long i)方法大致與其相同。
final void writeChars(String s, int start, int length)
將字符串轉(zhuǎn)化成UTF-8編碼的格式進(jìn)行存儲(chǔ)。
附:
UNICODE值 UTF-8編碼
U-00000000 - U-0000007F: 0xxxxxxx
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
可見(jiàn)對(duì)于在 0x00-0x7F范圍內(nèi)的UNICODE值(最大有效數(shù)位:7位),將會(huì)編碼成單字節(jié)的,會(huì)大大節(jié)約存儲(chǔ)空間。
對(duì)于在 0x80-0x7FF范圍內(nèi)的UNICODE(最大有效數(shù)位:11位),會(huì)編碼成雙字節(jié)的。先存儲(chǔ)原字節(jié)低5位的數(shù)位,且將最高位和次高位都置1,再次高位置0(writeByte((byte)(0xC0 | (code >> 6)));)。然后存儲(chǔ)后6位的字節(jié),將前兩位置10(writeByte((byte)(0x80 | (code & 0x3F)));)
對(duì)于其他的UNICODE值則
writeByte((byte)(0xE0 | (code >>> 12))); 4位
writeByte((byte)(0x80 | ((code >> 6) & 0x3F))); 5位
writeByte((byte)(0x80 | (code & 0x3F))); 3- 5位
final void writeString(String s) throws IOException
該函數(shù)首先用s.length()判斷該String總共有多少個(gè)字符
然后首先調(diào)用writeVInt寫入這個(gè)字符長(zhǎng)度
再調(diào)用writeChars(s,s.length())寫入字符
在inputStream中的readString()方法則與其相反,首先用readVInt()方法讀取字符長(zhǎng)度len 然后讀取len長(zhǎng)度的字符
protected final void flush() throws IOException
該方法調(diào)用另外一個(gè)方法flushBuffer將緩沖區(qū)中的數(shù)據(jù)輸出,然后清空緩沖區(qū);
abstract void flushBuffer(byte[] b, int len) throws IOException
可見(jiàn)flushBuffer方法是abstract的,即需要其子類對(duì)該方法進(jìn)行覆寫,以定位該輸出流的輸出方式。
final long getFilePointer() throws IOException
得到文件指針的位置,即得到輸出流已經(jīng)輸出的字節(jié)數(shù)。
public void seek(long pos) throws IOException
輸出緩沖區(qū)的內(nèi)容,然后將文件指針定位到long所指示的文件位置。
abstract long length() throws IOException
返回文件中已有的字節(jié)數(shù)。需要子類實(shí)現(xiàn)。
FSDirectory繼承了abstract類Directory
在該類中既有該類的一些初始化操作,又有對(duì)FSDirectory對(duì)象本身的一些操作,這是為什么把其構(gòu)造函數(shù)設(shè)置為私有的一部分原因
static final Hashtable DIRECTORIES = new Hashtable();
每新建一個(gè)FSDirectory都會(huì)將其加入到該Hashtable中來(lái)。名稱是FSDirectory對(duì)應(yīng)的File 值是該FSDirectory。
注意:final對(duì)象并非是不可更改的
static final String LOCK_DIR =
System.getProperty("org.apache.lucene.lockdir",
System.getProperty("java.io.tmpdir"));
首先看用戶是否注冊(cè)了"org.apache.lucene.lockdir"屬性,如果沒(méi)有則用JAVA虛擬機(jī)固有的"java.io.tmpdir"屬性
這個(gè)屬性是一個(gè)路徑,代表lucene的鎖文件鎖放的位置。
static final boolean DISABLE_LOCKS =
Boolean.getBoolean("disableLuceneLocks") || Constants.JAVA_1_1;
如果用戶注冊(cè)了"disableLuceneLocks"屬性且為false,或者JAVA的版本是1.1則無(wú)法使用鎖。
static FSDirectory getDirectory(String path, boolean create)
static FSDirectory getDirectory(File file, boolean create)
從得到一個(gè)指定路徑或者文件的FSDirectory如果在則取出,如果不存在則用其私有的構(gòu)造函數(shù)構(gòu)造一個(gè)
該類還有3個(gè)非static的類變量
private File directory = null; 索引目錄
private int refCount; 鎖目錄
private File lockDir; 索引目錄數(shù)目
實(shí)際上,初始化一個(gè)FSDirectory只需要初始化這3個(gè)變量即可
如果create的值為true 則:如果索引目錄是已經(jīng)存在的目錄,則會(huì)遍歷該目錄然后刪除每一個(gè)文件,如果鎖目錄是已存在的也會(huì)用list返回所有的文件然后調(diào)用file.delete() 刪除。 如果目錄不存在則創(chuàng)建一個(gè)新的。
注意:list()方法 會(huì)先用文件名進(jìn)行排序然后返回(a.txt會(huì)比b.txt先返回) 且delete方法刪除文件夾時(shí),只能刪除空文件夾。如果失敗則跳出程序,不會(huì)刪除在該文件夾之后返回的文件。(如果有aa.txt , ab/b.txt , b.txt , 則刪除時(shí)候由于a文件夾非空刪除失敗,則b.txt由于前面刪除失敗跳出程序,也不會(huì)被刪除,但是aa.txt被正常刪除)
private FSDirectory(File path, boolean create) throws IOException
私有的構(gòu)造函數(shù)
private synchronized void create() throws IOException
創(chuàng)建新的directory /lockDir目錄,當(dāng)目錄已存在時(shí)即清空該目錄,不存在即創(chuàng)建新的目錄。
final String[] list() throws IOException
以字符串文件名的形式返回索引目錄的所有文件
final boolean fileExists(String name) throws IOException
在索引目錄是否存在指定文件名的文件
final long fileModified(String name) throws IOException
static final long fileModified(File directory, String name)
返回該文件的最后修改時(shí)間,directory參數(shù)為相對(duì)路徑,第一個(gè)函數(shù)的相對(duì)路徑為索引目錄
void touchFile(String name) throws IOException
將該文件的最后修改時(shí)間設(shè)置為當(dāng)前時(shí)間
final long fileLength(String name) throws IOException
返回該文件的長(zhǎng)度
final void deleteFile(String name) throws IOException
刪除該文件
final synchronized void renameFile(String from, String to) throws IOException
重命名該文件
該方法會(huì)首先檢測(cè)新的文件名命名的文件是否已經(jīng)存在如果存在即刪除該文件,然后再將文件重新命名為新的文件名。
doug cutting在該方法的注釋上寫到:
1.刪除操作和重命名的操作不是原子的。
2.重命名操作在有些虛擬機(jī)上面不能正確的工作,如果重命名失敗則會(huì)采用手動(dòng)copy的方法。使用輸入輸出流將舊的文件的內(nèi)容寫入到新的文件中去,然后刪除舊的文件。
注意:該方法必須是同步的。
final OutputStream createFile(String name) throws IOException
用指定的文件名創(chuàng)建一個(gè)新的可寫的空文件 實(shí)際上返回的是FSOutputStream,注意這里的OutputStream并不是java的基礎(chǔ)類。而是doug cutting自己寫的一個(gè)文件隨即訪問(wèn)類。同理FSInputStream和InputStream也是Lucene自己的類。
final InputStream openFile(String name) throws IOException
從一個(gè)存在的文件打開(kāi)一個(gè)輸入流
getLockPrefix()
在FSDirectory中還有
private static MessageDigest DIGESTER;這個(gè)靜態(tài)變量是提供加密功能的
DIGESTER=MessageDigest.getInstance("MD5"),-----MD5加密算法
或者可以DIGESTER=MessageDigest.getInstance("SHA"),-----SHA加密算法
用于對(duì)鎖目錄的 文件名的加密
用法如下:
digest = DIGESTER.digest(dirName.getBytes()); dirName是需要被加密的字符串,這里是索引文件的目錄名,
在FSContext中,其應(yīng)用在 getLockPrefix() 該方法是為某個(gè)索引目錄創(chuàng)建其對(duì)應(yīng)的鎖目錄文件名。
首先返回經(jīng)過(guò)加密后的byte[] 數(shù)組digest,然后將digest按照每4個(gè)bit轉(zhuǎn)化為一個(gè)16進(jìn)制的字符,存進(jìn)一個(gè)StringBuffer中
其轉(zhuǎn)化類似與Base64編碼方式,不過(guò)要簡(jiǎn)單得多。
方法
Lockl makeLock(String name)
是從Directory中擴(kuò)展而來(lái)的,該方法返回一個(gè)Lock對(duì)象,該對(duì)象將會(huì)在介紹完Lucene的輸入輸出流之后介紹。
該方法比較簡(jiǎn)單,首先是調(diào)用了getLockPrefix() 方法,返回文件鎖的部分對(duì)象名,然后在該名稱后面加上鎖的特征名
譬如說(shuō)讀寫鎖 事務(wù)鎖
其名稱類似于下:
lucene-12c90c2c381bc7acbc4846b4ce97593b-write.lock
lucene-12c90c2c381bc7acbc4846b4ce97593b-commit.lock
這兩種鎖機(jī)制將會(huì)在后面介紹
最后通過(guò)一個(gè)匿名的內(nèi)部類返回一個(gè)經(jīng)過(guò)重載的Lock對(duì)象,該內(nèi)部類中的方法有鎖的創(chuàng)建,得到,釋放,以及檢測(cè),另外還有一個(gè)toString()方法返回鎖的名稱。
在FSDirectory類中有OutputStream和InputStream的實(shí)現(xiàn)類,這兩個(gè)虛類只是定義了一些操作,并沒(méi)有定義輸入或者輸出的設(shè)備。
Lucene在輸入輸出的設(shè)計(jì)上,將會(huì)由子類定義輸入輸出的設(shè)備。
FSOutputStream
在FSOutputStream中有一個(gè) RandomAccess File=new RandomAccessFile(path, "rw");
在對(duì)該輸出流的操作將用調(diào)用該file的相應(yīng)方法實(shí)現(xiàn)
最重要的
public final void flushBuffer(byte[] b, int size) throws IOException {
file.write(b, 0, size);
}
flushBuffer的調(diào)用將會(huì)將byte中的0--size范圍的數(shù)據(jù)寫入到文件path中去。
FSInputStream
最重要的
protected final void readInternal(byte[] b, int offset, int len)
throws IOException {
synchronized (file) {
long position = getFilePointer(); //得到該當(dāng)前文件指針
if (position != file.position) {
file.seek(position);
file.position = position;
}
int total = 0;
do {
//從文件中讀取指定長(zhǎng)度的字節(jié)到字節(jié)數(shù)組
// 在其基類InputStream中的refill()方法 將會(huì)調(diào)用 readInternal(buffer, 0, bufferLength);首先從文件中讀取字節(jié)到緩沖數(shù)組。
// 在InputStream中每次讀取操作都會(huì)調(diào)用readInternal方法,或者通過(guò)refill()方法間接調(diào)用該方法。
int i = file.read(b, offset+total, len-total); //將文件中的數(shù)據(jù)讀到緩沖區(qū)
if (i == -1)
throw new IOException("read past EOF");
file.position += i;
total += i;
} while (total < len);
}
}
該類提供了日期和字符串之間的相互轉(zhuǎn)化,實(shí)際上是 long型和String型的相互轉(zhuǎn)化,轉(zhuǎn)化時(shí)用到了一個(gè)不常用的
Long.toString(long,int);方法。是按指定的方式對(duì)long型進(jìn)行轉(zhuǎn)化
第一個(gè)參數(shù)是要轉(zhuǎn)化的long,第二個(gè)參數(shù)是轉(zhuǎn)化時(shí)候的基數(shù),如果基數(shù)是10就相當(dāng)于方法Long.toString(long);
這里使用的參數(shù)是最大值,即36== 10個(gè)數(shù)字+26個(gè)英文字母。這樣轉(zhuǎn)化出來(lái)的字符串長(zhǎng)度比較短,占用比較少的空間,
另外,在轉(zhuǎn)化時(shí),統(tǒng)一了轉(zhuǎn)化后的字符串長(zhǎng)度,如果不足9位(日期的long轉(zhuǎn)化后最高為9位,1970之后的日期可正確轉(zhuǎn)換),
統(tǒng)一長(zhǎng)度后的字符串可以通過(guò)比較字符串來(lái)比較日期的大小。
日期轉(zhuǎn)化成的字符串類似于
0fev8eza3
本來(lái)應(yīng)該是fev8eza3 采取了不足9位補(bǔ)0的方法。
private static int DATE_LEN = Long.toString(1000L*365*24*60*60*1000,
Character.MAX_RADIX).length();
計(jì)算出從1970年開(kāi)始后1000年的時(shí)間轉(zhuǎn)化為字符串后的長(zhǎng)度,所有轉(zhuǎn)化后的時(shí)間都不應(yīng)超過(guò)這個(gè)長(zhǎng)度,如果不足則在前面補(bǔ)0
可以通過(guò)字符串轉(zhuǎn)化為日期的函數(shù)計(jì)算出能表示的最大日期為
stringToTime("zzzzzzzzz");
打印出來(lái)是 Fri Apr 22 19:04:28 CST 5188
所以該函數(shù)能轉(zhuǎn)化的日期范圍為 1970-1-1~~5188-4-22
日期轉(zhuǎn)化為字符串
public static String timeToString(long time)
字符串轉(zhuǎn)化為日期
public static long stringToTime(String s)
實(shí)際上 函數(shù) LongToString(long i,int radix) 相當(dāng)于 先將i轉(zhuǎn)化為radix進(jìn)制的整數(shù),然后再用函數(shù)
LongToString(i)轉(zhuǎn)化為字符串。所以radix的值應(yīng)該在2--36之間如果不是 則按照10進(jìn)制計(jì)算。
Document是一些Field的集合,每個(gè)Field有一個(gè)名字和文本值,當(dāng)中的某些Field可能會(huì)隨著Documnet被存儲(chǔ)。這樣,每個(gè)Document應(yīng)該至少包含一個(gè)可以唯一標(biāo)示它的被存儲(chǔ)的Field
//Field集合
List fields = new Vector();
//增強(qiáng)因子,作用于該Document的所有Field
private float boost = 1.0f;
//向Document中添加Field
public final void add(Field field) {
fields.add(field);
}
//刪除指定名稱的第一個(gè)Field
public final void removeField(String name)
//刪除所有擁有指定名稱的Field
public final void removeFields(String name)
//得到指定名稱的第一個(gè)Field
public final Field getField(String name)
//以數(shù)組的形式返回指定名稱的所有Field
public final Field[] getFields(String name)
//得到所有Field的一個(gè)枚舉
public final Enumeration fields()
該類也重載了toString()方法
打印出所有Field的信息
package org.apache.lucene.document;
Field
是Document的一部分,每個(gè)Field有兩個(gè)部分組成 名字-值 對(duì) 名字是String 值 可以是String 和 Reader,如果是KeyWord類型的Field,那么值將不會(huì)被進(jìn)一步處理,像URL,Date等等。Field被存儲(chǔ)在Index中,以便于能以Hits的形式返回原有的Document
Field有3 個(gè)Boolean形的標(biāo)識(shí)
private boolean isStored = false; 被存儲(chǔ)
private boolean isIndexed = true; 被索引
private boolean isTokenized = true 被分割
通過(guò)調(diào)整這3個(gè)boolean的值,可以確定該Field的類型
Keyword true, true, false 一般存儲(chǔ) URL DATE 等關(guān)鍵字
UnIndexed true, false, false 一般是隨HITS查詢結(jié)果一起返回的信息
Text true, true, true
UnStored false, true, true
另外,還有一個(gè)重載的toString方法 可以打印出該Field的類型
float boost = 1.0f; 增強(qiáng)因子,用于排序的評(píng)分,作用于擁有該域(field)的所有文檔(document)