Feb 16, 2011

Apache Solr 1.4 Filter の作成 POSFilter

Tokenizer を作成したので、次はFilter を作ります。

Filter も Tokenizer と同様に、Factory クラスを作成し、Filter を create します。

Factoryクラスは、「 org.apache.solr.analysis.BaseTokenFilterFactory 」を継承し、
createメソッドを実装すればOKですが、設定ファイルをロードする必要がある場合などは、
「 org.apache.solr.util.plugin.ResourceLoaderAware 」を implement して、
inform メソッドを実装します。

このあたりは、Solr 本付属のソースや、
org.apache.solr.analysis.StopFilterFactory のソースなどが参考になります。

まずは、POSFilterFactory.class と、POSFilter.class を作成します。

POSFilterFactory.class で作成する 設定ファイルから読み込む POS情報ですが、
スレッド間で同期する必要がないので、Solr 本と同様に Set で実装します。

なので、POSFilterFactory のソースの抜粋は、以下のように。
public class POSFilterFactory extends BaseTokenFilterFactory implements ResourceLoaderAware {
    private Set<string> posSet;
    public void inform(ResourceLoader loader) {
        try {
            List<string> alist = loader.getLines(denyPOSFile);
            posSet = POSFilter.makePOSSet(alist);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public TokenStream create(TokenStream input) {
        return new POSFilter(input, posSet);
    }
}

public final class POSFilter extends TokenFilter {
    private final Set<string> posSet;

    public POSFilter(TokenStream input, Set<string> posSet) {
        super(input);
        this.posSet = posSet;
    }

    public final static Set<string> makePOSSet(List<string> posList) {
        if (posList == null)
            throw new NullPointerException("posList is null");
        return new HashSet<string>(posList);
    }

    public final Token next(Token token) throws IOException {
        Token t;
        while (true) {
            t = input.next(token);
            if (t == null)
                return null;
            if (posSet == null || !posSet.contains(t.type()))
                break;
        }
        return t;
    }
}


これで、fieldType の以下の部分までができました。
<fieldType name="text_ja" class="solr.TextField">
    <analyzer>
      <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ja.txt" />
      <tokenizer class="SenTokenizerFactory" />
      <filter class="POSFilterFactory" deny="pos-deny.txt" />
    </analyzer>
  </fieldType>

No comments:

Post a Comment