Lucene:分析Document源码

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的删除也是按照名称匹配方式实现的

以上纯属个人见解,如有问题请联本人!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章