Document类分析
到这里,我们首先需要了解一下Document的概念。Document的意思是文档,它在Lucene中代表一种逻辑文件。Lucene本身无法为物理文件建立索引,而只能识别并处理自己定义的Document文件。在一些时候,可以将Document与一个物理文件相对应,用一个Document来代替一个物理文件,不过多数情况下,Document和物理文件没有关系,它只是作为一种数据源的集合,向Lucene提供原始的要索引的文本内容。Lucene会从Document取出相关的数据源内容,并根据属性配置进行相应处理。接下来,我们继续分析Document类的内部实现。其源代码位于org.apache.lucene.document包下。
public final class Document implements java.io.Serializable { List fields = new Vector(); private float boost = 1.0f; /** Constructs a new document with no fields. */ public Document() {} public void setBoost(float boost) { this.boost = boost; } public float getBoost() { return boost; } public final void add(Field field) { fields.add(field); } public final void removeField(String name) { Iterator it = fields.iterator(); while (it.hasNext()) { Field field = (Field)it.next(); if (field.name().equals(name)) { it.remove(); return; } } } public final void removeFields(String name) { Iterator it = fields.iterator(); while (it.hasNext()) { Field field = (Field)it.next(); if (field.name().equals(name)) { it.remove(); } } } public final Field getField(String name) { for (int i = 0; i < fields.size(); i++) { Field field = (Field)fields.get(i); if (field.name().equals(name)) return field; } return null; } public final String get(String name) { for (int i = 0; i < fields.size(); i++) { Field field = (Field)fields.get(i); if (field.name().equals(name) && (!field.isBinary())) return field.stringValue(); } return null; } /** Returns an Enumeration of all the fields in a document. */ public final Enumeration fields() { return ((Vector)fields).elements(); } public final Field[] getFields(String name) { List result = new ArrayList(); for (int i = 0; i < fields.size(); i++) { Field field = (Field)fields.get(i); if (field.name().equals(name)) { result.add(field); } } if (result.size() == 0) return null; return (Field[])result.toArray(new Field[result.size()]); } public final String[] getValues(String name) { List result = new ArrayList(); for (int i = 0; i < fields.size(); i++) { Field field = (Field)fields.get(i); if (field.name().equals(name) && (!field.isBinary())) result.add(field.stringValue()); } if (result.size() == 0) return null; return (String[])result.toArray(new String[result.size()]); } public final byte[][] getBinaryValues(String name) { List result = new ArrayList(); for (int i = 0; i < fields.size(); i++) { Field field = (Field)fields.get(i); if (field.name().equals(name) && (field.isBinary())) result.add(field.binaryValue()); } if (result.size() == 0) return null; return (byte[][])result.toArray(new byte[result.size()][]); } public final byte[] getBinaryValue(String name) { for (int i=0; i < fields.size(); i++) { Field field = (Field)fields.get(i); if (field.name().equals(name) && (field.isBinary())) return field.binaryValue(); } return null; } /** Prints the fields of a document for human consumption. */ public final String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("Document<"); for (int i = 0; i < fields.size(); i++) { Field field = (Field)fields.get(i); buffer.append(field.toString()); if (i != fields.size()-1) buffer.append(" "); } buffer.append(">"); return buffer.toString(); } }
根据源码,我们知道,Document内部创建了一个Vector对象,并将其赋给名为fields的List类型变量。通过调用List的add方法,实现了Document添加Field的add方法。Document也有setBoost和getBoost方法,且其boost值默认也是1.0f。不过,与Fields类中setBoost和getBoost方法不同的是,它针对一个Document实例设置其boost值,而不是针对一个具体的Fields实例,而一个Document实例可以添加一个或多个Fields对象。
removeField方法用于删除一个Field,如果有多个名字相同的Field,则删除其中第一个被添加的Field。如果没有相应名字的Field,则Document保持不变。该方法首先定义了一个迭代器(Iterator)实例,并调用fields的iterator方法为其赋值,然后利用循环遍历的方法,查找并移除。
removeFields方法用于删除多个名字相同的Field,如果没有相应名字的Field,则Document保持不变。内部实现方法和removeField方法完全一样。
getField方法用于返回一个给定名字且不是二进制的Field实例,如果有多个Field的名字一样,就返回其中第一个Field的信息。如果该Field存在,则返回该Field的值;如果不存在,则返回null。该方法定义一个Field实例,并调用变量fields的get方法,将结果强制转换为Field类型为其赋值。之后判断是否存在这样一个实例,如果存在,返回结果。
get方法用于返回一个给定名称且不是二进制的Field的值。如果该Field存在,则返回该Field的值;如果不存在,则返回null。该方法与getField原理相似只不过返回的是Field的值,而不是Field对象。
Fields方法用于返回一个所有Field的枚举。通过调用变量fields的elements方法实现。
getFields方法根据名称得到一个Field的数组;getValues方法根据名称得到一个Field的值的数组;getBinaryValues方法返回一个二进制类型的给定名称的Field数组;getBinaryValue返回一个二进制类型的给定名称的Field的值,如果有多个该类型Field名字相同,则返回第一个;toString方法用于将Document转换为string格式输出。这些方法内部实现都比较简单,可参考前面的代码分析过程进行分析。