lucene in action笔记之一索引

  1. 执行最简单索引过程需要的几个类:IndexWriter、Directory、Analyzer、Document、Field。简单例子如下所示:
    public static int index(File indexDir, File dataDir)
        throws IOException {
    
        if (!dataDir.exists() || !dataDir.isDirectory()) {
          throw new IOException(dataDir
            + " does not exist or is not a directory");
        }
        if (dataDir.isHidden() || !dataDir.canRead()||!dataDir.getName().endsWith(".txt")) {
        	throw new IOException(dataDir
        	        + " error!");
        }
    
        IndexWriter writer = new IndexWriter(indexDir,
          new StandardAnalyzer(), true);
        writer.setUseCompoundFile(false);
        //使用 IndexWriter's setUseCompoundFile(true) 创建复合文件,减少索引文件数量。
        
        System.out.println("Indexing " + dataDir.getCanonicalPath());
        
        Document doc = new Document();
        doc.add(Field.Text("contents", new FileReader(dataDir)));
        doc.add(Field.Keyword("filename", dataDir.getCanonicalPath()));
        writer.addDocument(doc);
    
        int numIndexed = writer.docCount();
        writer.optimize();
        writer.close();
        return numIndexed;
      }
     
  2. 索引过程的三个主要阶段:将数据转换成文本、分析文本、将分析后的文本保存到索引库中。              注1:Lucene只能索引文本文件,即.txt文件。注2:分析数据最有代表性的操作是要从输入中去掉一些使用很频繁但却没有实际意义的词,比如英文文本中的一些停止词(a,an,the,on,in等)。注3:数据是以倒排索引的数据结构进行存储,原因:倒排索引并不是回答“这个文档中包含那些单词?”,而是经过优化以后用来快速回答“那些文档包含词x?”
  3. 基本索引操作:1)Lucene允许那些拥有不同Field对象的Document对象在一个索引中共存;2)如果要索引一个基本词和它所有的同义词,可以同给一个相同的域赋予多个不同的值;3)删除索引中的文档用IndexReader,注意直到IndexReader调用close()后才真正将他们删除。4)每一个文档都有一个唯一的内部编号,但这不是永久的,编号是从0开始;
  4. IndexReader的几个方法:1) maxDoc():返回下一个可得到的文档的内部编号,编号从0开始;2)numDocs():返回索引中文档的数量;3)hasDeletions():检查一个索引是否包含了带有删除标记的文档;4) isDeleted(int):检查一个特定编号的文档状态;5)delete(int),delete(Term):删除指定文档。
  5. 对Document和Field调用setBoost(float)进行加权处理会在搜索时发挥作用。lucene的搜索结果是根据文档对象和查询的匹配相关度来排序,且每个匹配的文档对象都会有一个评分。评分公式有多个因子组成,加权因子就是其中一个。
  6. Lucene中自带的DateField类不能处理1970年之前的日期。
  7. Lucene通过在内部将数值处理为字符串的方式索引数值。如果需要索引的数字在自由形式文本里面出现,首先要做的就是选择支持数字的Analyzer类。
  8. 当索引数值域对象时,如果希望利用他们来进行范围查询,就用0填充。
  9. 如果希望能够按照某个域对象的值排序,就必须将它作为一个被索引但不被语汇单元化(分析器的一些操作,如提取单词、去除标点等)的域对象。用于排序的域对象一定是可以被转换为整型,浮点或者字符串的对象。
  10. 较小的maxFactor参数是内存的使用减少,并使索引更新的频率升高。---->数据实时性更强,但降低了索引过程的速度。注:较大的MaxFactor参数会导致索引文件数量增多,从而降低用户搜索的速度。
  11. 较大的maxMergeDocs参数更适用于批量索引的情况,较小的maxMergeDocs参数更适用于交互性较强的索引。
  12. 应用程序在处理maxFieldLength时,应该把它设置成Integer.MAX_VALUE。maxFieldLength的值可在索引过程中的任意时刻被修改,并对其后添加所有文档起作用。
    private void addDocuments(Document doc, int maxFieldLength)
        throws IOException {
        IndexWriter writer = new IndexWriter(dir, new SimpleAnalyzer(),
          true);
        writer.maxFieldLength = maxFieldLength;
        writer.addDocument(doc);
        writer.optimize();
        writer.close();
      }
  13. 对索引进行优化会把所有段合并成单个段,可以通过调用IndexWriter的optimize()方法来优化。
  14. 对索引优化只会提高搜索操作的速度,他对索引过程的速度没有影响。
  15. 在索引过程中对索引进行优化的做法并不值得提倡。优化最佳时机是在索引过程结束之后,且当你确认在此后的一段时间不会对索引文件进行更改的时候。
  16. 并发访问的原则:1)在某一时刻,只允许执行一个修改索引的操作。也就是说,在同一时间,一个索引文件只能被一个IndexWriter或IndexReader对象打开。   2) 无论任何时候,包括索引文件正在优化,或正在对索引执行文档的添加、更新或删除操作时,任意数量的只读操作都可以同时执行。
  17. IndexWriter和IndexReader都是线程安全的。但仍然注意在同一索引上不能同时打开IndexWriter和IndexReader。
  18. 索引锁是基于文件的,各个索引都有自认的所文件集,在默认情况下,所有的锁文件都会被创建在计算机的临时目录中,这个目录由Java的java.io.tmpdir中的系统属性所指定。
  19. write.lock文件用于阻止进程试图并发的修改一个索引。   commit.lock文件在对段进行读或合并操作时使用。强烈建议:不要对Lucene的锁机制进行随意修改。
  20. 对Lucene写入索引的过程进行调试,可以将IndexWriter的公有变量infoStream设定为OutputStream中的一种,诸如System.out等,从而使Lucene输出关于进行索引操作时的一些具体信息。如下所示:
    IndexWriter writer = new IndexWriter(dir, new SimpleAnalyzer(), true);
    writer.infoStream = System.out;
    ...
     

相关推荐