1.聲明
當前內容主要用於本人學習和複習,當前內容爲Document源碼分析
由於前面測試和使用了Lucene實現了增刪查改,發現當前所使用的模型就是Document,所以決定分析以下該類主要的數據模型和方式,以便後面的理解
2.查看Document類繼承和實現
public final class Document implements Iterable<IndexableField>
1.發現該類是最終類,所以無法繼承和重寫其中的屬性和內容
2.發現該類只實現了一個索引字段迭代的功能
3.查看Document類的構造函數
public Document() {}
一個非常簡單的無參構造函數
4.查看Document類的屬性
private final List<IndexableField> fields = new ArrayList<>();
private final static String[] NO_STRINGS = new String[0];
1.當前的Document中的所有的索引字段使用List集合來維護
2.由於使用了List集合,說明當前的索引字段可以重複可以具有多個相同的IndexFiled
5.查看Document類中的方法
1.添加索引字段方法:add(IndexableField)
public final void add(IndexableField field) {
fields.add(field);
}
直接在集合中添加就完事了(說明Document實際上就是一堆IndexableFiled的集合,並且該集合中的元素可重複)
2.刪除索引字段
// 直接迭代按照索引字段的名稱方式比較,然後刪除第一個匹配的元素
public final void removeField(String name) {
Iterator<IndexableField> it = fields.iterator();
while (it.hasNext()) {
IndexableField field = it.next();
if (field.name().equals(name)) {
it.remove();
return;
}
}
}
// 直接迭代按照索引字段的名稱方式比較,刪除所有匹配的字段
public final void removeFields(String name) {
Iterator<IndexableField> it = fields.iterator();
while (it.hasNext()) {
IndexableField field = it.next();
if (field.name().equals(name)) {
it.remove();
}
}
}
就是一個按照IndexableField的名稱進行迭代然後刪除,只是一個是刪除第一個元素,而後面的removeFields是刪除所有匹配的元素
3.通過索引字段名稱獲取對應的二進制值
//實際上就是迭代,按照名稱方式獲取所有匹配的BytesRef值,主要通過binaryValue方法獲取
public final BytesRef[] getBinaryValues(String name) {
final List<BytesRef> result = new ArrayList<>();
for (IndexableField field : fields) {
if (field.name().equals(name)) {
final BytesRef bytes = field.binaryValue();
if (bytes != null) {
result.add(bytes);
}
}
}
return result.toArray(new BytesRef[result.size()]);
}
//實際上就是迭代,按照名稱方式獲取第一個匹配的BytesRef值,主要通過binaryValue方法獲取
public final BytesRef getBinaryValue(String name) {
for (IndexableField field : fields) {
if (field.name().equals(name)) {
final BytesRef bytes = field.binaryValue();
if (bytes != null) {
return bytes;
}
}
}
return null;
}
發現這個就是按照名稱迭代,獲取其binaryValue的值,其結果類型爲BytesRef
4.通過名稱獲取索引字段
// 直接獲取第一個匹配的索引字段
public final IndexableField getField(String name) {
for (IndexableField field : fields) {
if (field.name().equals(name)) {
return field;
}
}
return null;
}
// 獲取所有匹配的索引字段
public IndexableField[] getFields(String name) {
List<IndexableField> result = new ArrayList<>();
for (IndexableField field : fields) {
if (field.name().equals(name)) {
result.add(field);
}
}
return result.toArray(new IndexableField[result.size()]);
}
就是按照名稱在List集合中找到匹配的IndexableField
5.查看getFileds方法
public final List<IndexableField> getFields() {
return Collections.unmodifiableList(fields);
}
表示返回一個不可修改的索引字段的集合
6.通過字段名稱獲取String類型的值
// 實際就是按照名稱匹配,並直接獲取所有匹配stringValue
public final String[] getValues(String name) {
List<String> result = new ArrayList<>();
for (IndexableField field : fields) {
if (field.name().equals(name) && field.stringValue() != null) {
result.add(field.stringValue());
}
}
if (result.size() == 0) {
return NO_STRINGS;
}
return result.toArray(new String[result.size()]);
}
// 實際就是按照名稱匹配,並直接獲取第一個匹配stringValue
public final String get(String name) {
for (IndexableField field : fields) {
if (field.name().equals(name) && field.stringValue() != null) {
return field.stringValue();
}
}
return null;
}
就是返回調用的IndexableField的stringValue方法獲取String類型的值
7.查看clear方法
public void clear() {
fields.clear();
}
直接就是List的清空方法
6.總結
1.當前的Lucene中的Document實際上就是IndexableField的集合,並且該集合中的元素是可以重複的(那麼查找就是可以通過同名的索引一起查詢)
2.IndexableField具有BytesRef類型的數據和String類型的數據,通過使用不同的方法獲取
3.Document的所有的獲取方式都是按照IndexableField的名稱方式獲取(實際就是迭代獲取的)
4.Document的刪除也是按照名稱匹配方式實現的
以上純屬個人見解,如有問題請聯本人!