zoukankan      html  css  js  c++  java
  • 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进行管理判断的方法信息。

  • 相关阅读:
    jdk8u144安装在centos7上
    事件对象(示例、封装函数EventUtil())
    事件处理程序
    取消冒泡
    编程挑战JavaScript进阶篇(慕课网题目)
    网页卷去的距离与偏移量
    DOM编程练习(慕课网题目)
    浏览器窗口可视区域大小
    网页尺寸scrollHeight/offsetHeight
    替换元素节点replaceChild()
  • 原文地址:https://www.cnblogs.com/zwb7926/p/3115577.html
Copyright © 2011-2022 走看看