繁体   English   中英

Solr 中的电话号码同义词过滤器/分词器?

[英]A phone number synonym-like filter/tokenizer in Solr?

我正在尝试使用如下查询使 Solr 搜索像这样+79876543210存储的电话号码:

+79876543210
 79876543210
 89876543210  <-- '+7' is replaced with region specific code '8'
  9876543210  <-- '+7' entirely removed

这只是一个例子。 另一个是有线电话号码:

+78662123456  <-- '+78662' is a specific region code
 78662123456
 88662123456
  8662123456
      123456  <-- region code entirely removed

我可以解决这个问题的一种方法是使用一个单独的字段,其中填充了这些变体并且仅在搜索期间使用。 但这在突出显示方面存在问题(它返回<em>123456</em>以突出显示,而向用户显示的实际值是+78662123456 )。 我认为也许最好只使用 Solr 来制作这些索引,但是怎么做呢?

首先想到的是使用托管同义词过滤器并将它们与每条添加的记录一起传递。 文档明确指出:

在重新加载 Solr 集合(或单服务器模式下的 Solr 核心)之前,通过此 REST API 对托管资源所做的更改不会应用于活动的 Solr 组件。

所以每次添加记录后都重新加载一个核心不是go的方法。其他问题涉及使这些同义词与记录保持同步。

可以有另一种方法来解决这个问题吗?

多亏了这条评论(来自 MatsLindh),我设法组装了一个基于内置EdgeNGramTokenFilter的简单过滤器:

package com.step4;

import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ReverseCustomFilter extends TokenFilter {
    private static final PatternReplacementPair[] phonePatterns = {
            new PatternReplacementPair("\\+7", "7"),
            new PatternReplacementPair("\\+7", "8"),
            new PatternReplacementPair("\\+7", ""),
            new PatternReplacementPair("\\+78662", ""),
            new PatternReplacementPair("\\+78663", ""),
    };

    private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
    private final PositionIncrementAttribute posIncrAtt = addAttribute(PositionIncrementAttribute.class);
    private int curPatternIndex;
    private int curPosIncr;
    private State curState;

    public ReverseCustomFilter(TokenStream input) {
        super(input);
    }

    @Override
    public final boolean incrementToken() throws IOException {
        while (true) {
            if (curPatternIndex == 0) {
                if (!input.incrementToken()) {
                    return false;
                }

                curState = captureState();
                curPosIncr += posIncrAtt.getPositionIncrement();
                curPatternIndex = 1;
            }

            if (curPatternIndex <= phonePatterns.length) {
                PatternReplacementPair replacementPair = phonePatterns[curPatternIndex - 1];
                curPatternIndex++;

                restoreState(curState);
                Matcher matcher = replacementPair.getPattern().matcher(termAtt);
                if (matcher.find()) {
                    posIncrAtt.setPositionIncrement(curPosIncr);
                    curPosIncr = 0;

                    String replaced = matcher.replaceFirst(replacementPair.getReplacement());
                    termAtt.setEmpty().append(replaced);

                    return true;
                }
            }
            else {
                restoreState(curState);
                posIncrAtt.setPositionIncrement(0);

                curPatternIndex = 0;
                return true;
            }
        }
    }

    @Override
    public void reset() throws IOException {
        super.reset();
        curPatternIndex = 0;
        curPosIncr = 0;
    }

    @Override
    public void end() throws IOException {
        super.end();
        posIncrAtt.setPositionIncrement(curPosIncr);
    }

    private static class PatternReplacementPair {
        private final Pattern pattern;
        private final String replacement;
        public PatternReplacementPair(String pattern, String replacement) {
            this.pattern = Pattern.compile(pattern);
            this.replacement = replacement;
        }

        public Pattern getPattern() {
            return pattern;
        }

        public String getReplacement() {
            return replacement;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM