lucene demo引出的思考

org.apache.lucene.demo.IndexFiles 类中,使用递归的方式去索引文件 。在构造了一个IndexWriter索引器之后 ,就可以向索引器中添加Doucument了,执行真正地建立索引的过程。遍历每个目录,因为每个目录中可能还存在目录,进行深度遍历,采用递归技术找到处于叶节点处的文件(普通的具有扩展名的文件,比如my.txt文件),然后调用如下代码中:

[java] view plaincopy
 
  1. static void indexDocs(IndexWriter writer, File file)  
  2.     throws IOException {  
  3.     // file可以读取  
  4.     if (file.canRead()) {  
  5.       if (file.isDirectory()) { // 如果file是一个目录(该目录下面可能有文件、目录文件、空文件三种情况)  
  6.         String[] files = file.list(); // 获取file目录下的所有文件(包括目录文件)File对象,放到数组files里  
  7.         // 如果files!=null  
  8.         if (files != null) {  
  9.           for (int i = 0; i < files.length; i++) { // 对files数组里面的File对象递归索引,通过广度遍历  
  10.             indexDocs(writer, new File(file, files[i]));  
  11.           }  
  12.         }  
  13.       } else { // 到达叶节点时,说明是一个File,而不是目录,则建立索引  
  14.         System.out.println("adding " + file);  
  15.         try {  
  16.           writer.addDocument(FileDocument.Document(file));  
  17.         }  
  18.         catch (FileNotFoundException fnfe) {  
  19.           ;  
  20.         }  
  21.       }  
  22.     }  
  23. }  

上面这一句:

writer.addDocument(FileDocument.Document(file));

其实做了很多工作。每当递归到叶子节点,获得一个文件,而非目录文件,比如文件myWorld.txt。然后对这个文件进行了复杂的操作 :

先根据由myWorld.txt构造的File对象f,通过f获取myWorld.txt的具体信息,比如存储路径、修改时间等等,构造多个Field对象,再由这些不同Field的聚合,构建出一个Document对象 ,最后把Document对象加入索引器IndexWriter对象中 ,通过索引器可以 这些聚合的Document Field中信息进行分词、过滤处理 ,方便检索。

[java] view plaincopy
 
  1. org.apache.lucene.demo.FileDocument类的源代码如下所示:  
  2. package org.apache.lucene.demo;  
  3. import java.io.File;  
  4. import java.io.FileReader;  
  5. import org.apache.lucene.document.DateTools;  
  6. import org.apache.lucene.document.Document;  
  7. import org.apache.lucene.document.Field;  
  8. public class FileDocument {  
  9. public static Document Document(File f)  
  10.        throws java.io.FileNotFoundException {  
  11.     // 实例化一个Document  
  12.     Document doc = new Document();  
  13.     // 根据传进来的File f,构造多个Field对象,然后把他们都添加到Document中  
  14.     // 通过f的所在路径构造一个Field对象,并设定该Field对象的一些属性:  
  15.     // “path”是构造的Field的名字,通过该名字可以找到该Field  
  16.     // Field.Store.YES表示存储该Field;Field.Index.UN_TOKENIZED表示不对该Field进行分词,但是对其进行索引,以便检索  
  17.     doc.add(new Field("path", f.getPath(), Field.Store.YES, Field.Index.UN_TOKENIZED));  
  18.    // 构造一个具有最近修改修改时间信息的Field  
  19.     doc.add(new Field("modified",  
  20.         DateTools.timeToString(f.lastModified(), DateTools.Resolution.MINUTE),  
  21.         Field.Store.YES, Field.Index.UN_TOKENIZED));  
  22.     // 构造一个Field,这个Field可以从一个文件流中读取,必须保证由f所构造的文件流是打开的  
  23.     doc.add(new Field("contents"new FileReader(f)));  
  24.     return doc;  
  25. }  
  26. private FileDocument() {}  
  27. }  

通过上面的代码,可以看出Field是何其的重要,必须把Field完全掌握了。

Field类定义了两个很有用enum:Store和Index,用它们来设置对Field进行索引时的一些属性。

[java] view plaincopy
 
  1. /** Specifies whether and how a field should be stored. */  
  2.  public static enum Store {  
  3.    /** Store the original field value in the index. This is useful for short texts 
  4.     * like a document's title which should be displayed with the results. The 
  5.     * value is stored in its original form, i.e. no analyzer is used before it is 
  6.     * stored. 
  7.     */  
  8.    YES {  
  9.      @Override  
  10.      public boolean isStored() { return true; }  
  11.    },  
  12.    /** Do not store the field value in the index. */  
  13.    NO {  
  14.      @Override  
  15.      public boolean isStored() { return false; }  
  16.    };  
  17.    public abstract boolean isStored();  
  18.  }  
  19.  /** Specifies whether and how a field should be indexed. */  
  20.  public static enum Index {  
  21.    /** Do not index the field value. This field can thus not be searched, 
  22.     * but one can still access its contents provided it is 
  23.     * {@link Field.Store stored}. */  
  24.    NO {  
  25.      @Override  
  26.      public boolean isIndexed()  { return false; }  
  27.      @Override  
  28.      public boolean isAnalyzed() { return false; }  
  29.      @Override  
  30.      public boolean omitNorms()  { return true;  }     
  31.    },  
  32.    /** Index the tokens produced by running the field's 
  33.     * value through an Analyzer.  This is useful for 
  34.     * common text. */  
  35.    ANALYZED {  
  36.      @Override  
  37.      public boolean isIndexed()  { return true;  }  
  38.      @Override  
  39.      public boolean isAnalyzed() { return true;  }  
  40.      @Override  
  41.      public boolean omitNorms()  { return false; }        
  42.    },  
  43.    /** Index the field's value without using an Analyzer, so it can be searched. 
  44.     * As no analyzer is used the value will be stored as a single term. This is 
  45.     * useful for unique Ids like product numbers. 
  46.     */  
  47.    NOT_ANALYZED {  
  48.      @Override  
  49.      public boolean isIndexed()  { return true;  }  
  50.      @Override  
  51.      public boolean isAnalyzed() { return false; }  
  52.      @Override  
  53.      public boolean omitNorms()  { return false; }        
  54.    },  
  55.    /** Expert: Index the field's value without an Analyzer, 
  56.     * and also disable the storing of norms.  Note that you 
  57.     * can also separately enable/disable norms by calling 
  58.     * {@link Field#setOmitNorms}.  No norms means that 
  59.     * index-time field and document boosting and field 
  60.     * length normalization are disabled.  The benefit is 
  61.     * less memory usage as norms take up one byte of RAM 
  62.     * per indexed field for every document in the index, 
  63.     * during searching.  Note that once you index a given 
  64.     * field <i>with</i> norms enabled, disabling norms will 
  65.     * have no effect.  In other words, for this to have the 
  66.     * above described effect on a field, all instances of 
  67.     * that field must be indexed with NOT_ANALYZED_NO_NORMS 
  68.     * from the beginning. */  
  69.    NOT_ANALYZED_NO_NORMS {  
  70.      @Override  
  71.      public boolean isIndexed()  { return true;  }  
  72.      @Override  
  73.      public boolean isAnalyzed() { return false; }  
  74.      @Override  
  75.      public boolean omitNorms()  { return true;  }        
  76.    },  
  77.    /** Expert: Index the tokens produced by running the 
  78.     *  field's value through an Analyzer, and also 
  79.     *  separately disable the storing of norms.  See 
  80.     *  {@link #NOT_ANALYZED_NO_NORMS} for what norms are 
  81.     *  and why you may want to disable them. */  
  82.    ANALYZED_NO_NORMS {  
  83.      @Override  
  84.      public boolean isIndexed()  { return true;  }  
  85.      @Override  
  86.      public boolean isAnalyzed() { return true;  }  
  87.      @Override  
  88.      public boolean omitNorms()  { return true;  }        
  89.    };  

Field类中还有一个内部类,它的声明如下:

[java] view plaincopy
 
  1. public static enum TermVector {  
  2.       
  3.     /** Do not store term vectors.  
  4.      */  
  5.     NO {  
  6.       @Override  
  7.       public boolean isStored()      { return false; }  
  8.       @Override  
  9.       public boolean withPositions() { return false; }  
  10.       @Override  
  11.       public boolean withOffsets()   { return false; }  
  12.     },  
  13.       
  14.     /** Store the term vectors of each document. A term vector is a list 
  15.      * of the document's terms and their number of occurrences in that document. */  
  16.     YES {  
  17.       @Override  
  18.       public boolean isStored()      { return true;  }  
  19.       @Override  
  20.       public boolean withPositions() { return false; }  
  21.       @Override  
  22.       public boolean withOffsets()   { return false; }  
  23.     },  
  24.       
  25.     /** 
  26.      * Store the term vector + token position information 
  27.      *  
  28.      * @see #YES 
  29.      */   
  30.     WITH_POSITIONS {  
  31.       @Override  
  32.       public boolean isStored()      { return true;  }  
  33.       @Override  
  34.       public boolean withPositions() { return true;  }  
  35.       @Override  
  36.       public boolean withOffsets()   { return false; }  
  37.     },  
  38.       
  39.     /** 
  40.      * Store the term vector + Token offset information 
  41.      *  
  42.      * @see #YES 
  43.      */   
  44.     WITH_OFFSETS {  
  45.       @Override  
  46.       public boolean isStored()      { return true;  }  
  47.       @Override  
  48.       public boolean withPositions() { return false; }  
  49.       @Override  
  50.       public boolean withOffsets()   { return true;  }  
  51.     },  
  52.       
  53.     /** 
  54.      * Store the term vector + Token position and offset information 
  55.      *  
  56.      * @see #YES 
  57.      * @see #WITH_POSITIONS 
  58.      * @see #WITH_OFFSETS 
  59.      */   
  60.     WITH_POSITIONS_OFFSETS {  
  61.       @Override  
  62.       public boolean isStored()      { return true;  }  
  63.       @Override  
  64.       public boolean withPositions() { return true;  }  
  65.       @Override  
  66.       public boolean withOffsets()   { return true;  }  
  67.     };  

  

这是一个与词条有关的枚举类型。

在3.0之前的lucene中,通常store index termvector都是被设置为静态内部类。。3.0开始设置为枚举类型。。。。。。

 

同时,Field的值可以构造成很多类型,Field类中定义了4种:String、Reader、byte[]、TokenStream。

然后就是Field对象的构造,应该看它的构造方法,它有9种构造方法:

 

还要注意了,通过Field类的声明:

public final class Field extends AbstractField implements Fieldable , Serializable

可以看出,应该对它继承的父类AbstractField类 有一个了解,下面的是AbstractField类的属性:

[java] view plaincopy
 
  1. protected String name = "body";  
  2. protected boolean storeTermVector = false;  
  3. protected boolean storeOffsetWithTermVector = false;  
  4. protected boolean storePositionWithTermVector = false;  
  5. protected boolean omitNorms = false;  
  6. protected boolean isStored = false;  
  7. protected boolean isIndexed = true;  
  8. protected boolean isTokenized = true;  
  9. protected boolean isBinary = false;  
  10. protected boolean isCompressed = false;  
  11. protected boolean lazy = false;  
  12. protected float boost = 1.0f;  
  13. protected Object fieldsData = null;  

还有Field实现了Fieldable接口 ,添加了 一些对对应的Document中的Field进行管理判断的方法信息。

原文地址:https://www.cnblogs.com/zwb7926/p/3115577.html