Lucene可扩展性-数据写入

Lucene代码拥有很强的扩展性,很多的关键代码都提供了用户自定义方式,可以根据特定的场景自定义处理方式,这篇文章就探讨一下lucene在数据写入过程中有哪些可扩展的地方。

下面是lucene数据写入的代码:

  • 自定义分词器

一个分词器有以下几个属性:

Filter : 分词过滤器 , 比如:LowerCaseFilterFactory,小写转换

Tokenizer:分词处理器,用于具体的分词处理

Attribute:分词属性对象,包括CharTermAttribute,PayloadAttribute等等,用于存储分词之后的值。

其中Tokenizer,Filter 是同级的,多个Filter 和Tokenizer组成一个相互引用的串,一次处理传来的文本值,看下StandardAnalyzer分词器中是如何相互引用的

Field的文本值首先进入stopFilter中的incrementToken方法中处理,并以此调用之前的类的incrementToken完成对整个串的调用。

自定义分词器需要继承Analyzer类,createComponent方法获取分词器对象,下面是一个自定义分词器的完整的例子:

public class PayloadAnylzer extends Anlyzer{

     /** Default maximum allowed token length */
  public static final int DEFAULT_MAX_TOKEN_LENGTH = 255;

  private int maxTokenLength = DEFAULT_MAX_TOKEN_LENGTH;

  /** An unmodifiable set containing some common English words that are usually not
  useful for searching. */
  public static final CharArraySet STOP_WORDS_SET = StopAnalyzer.ENGLISH_STOP_WORDS_SET; 

  private char delimiter;

  public PayloadAnylzer(char delimiter){
      this.delimiter = delimiter;
  }
  
  public void setMaxTokenLength(int length) {
    maxTokenLength = length;
  }

  public int getMaxTokenLength() {
    return maxTokenLength;
  }


  protected TokenStreamComponents createComponents(final String fieldName) {
    Tokenizer src = new PayloadTokenizer(this.delimiter);
    tok = new LowerCaseFilter(tok);
    tok = new StopFilter(tok, stopwords);
    return new TokenStreamComponents(src, tok) {
      @Override
      protected void setReader(final Reader reader) throws IOException {
        int m = StandardAnalyzer.this.maxTokenLength;
        if (src instanceof StandardTokenizer) {
          ((StandardTokenizer)src).setMaxTokenLength(m);
        } else {
          ((StandardTokenizer40)src).setMaxTokenLength(m);
        }
        super.setReader(reader);
      }
    };
  }
}

}
  • 不同的列选择不同的分词器

    Lucene提供了为不同的列选择不同分词器的能力,lucene包里面有个PerFieldAnalyzerWrapper类,解决了这一问题,用法如下:

    PerFieldAnalyzerWrapper aWrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer()); 
    aWrapper.addAnalyzer("firstname", new KeywordAnalyzer()); 
    aWrapper.addAnalyzer("lastname", new KeywordAnalyzer()); 

    上面的例子中列"firstname"和"lastname"会使用KeywordAnalyzer作为分词器,其余的列会使用的默认的分词器StandardAnalyzer。其中aWrapper 可以被当作任何analyzer来使用,用于索引和查询数据。下面是一个完整的例子:

  • 自定义codec

  Codec是lucene与文件交互的组件,通过自定义codec可以改变文件lucene中个文件存储和读取的方式,首先继承类FilterCodec,复写其中的方法,下面是一个自定义codec的例子:

Lucene中所有的codec都需要在services下的文件org.apache.lucene.codecs.codec中记录,如下:

  • 自定义indexingchain

   indexingchain是数据写入的核心类,包括数据的写入和刷盘。Indexwriter类中提供了indexingchain的set方法:

通过复写DocConsumer中的三个方法实现自定义indexingchain。

  • 自定义mergePolicy

     mergePolicy是用于段检测,找到符合合并的段,并将所有符合合并的段封装到内部类OneMerge中,用于后续的合并。

Lucene的indexwriterConfig中提供了set方法:

Lucene的默认实现是TieredMergePolicy,通过重写父类MergePolicy中的findMerges等方法可完成自定义mergePolicy。

 

  • 自定义mergescheduler

    mergescheduler是合并的核心类,执行真正的合并操作,Lucene的indexwriterConfig中提供了set方法:

复写类MergeScheduler中的merge等方法实现自定义mergescheduler。

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值