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的删除也是按照名称匹配方式实现的
以上纯属个人见解,如有问题请联本人!