0

我正在 Solr 中使用 WordDelimiterFilter 进行一些测试,但它不会保留我传递给它的受保护单词列表。请您检查代码和输出示例并建议哪个部分丢失或使用不当?

运行此代码:

private static Analyzer getWordDelimiterAnalyzer() {
    return new Analyzer() {
        @Override
        public TokenStream tokenStream(String fieldName, Reader reader) {
            TokenStream stream = new StandardTokenizer(Version.LUCENE_32, reader);
            WordDelimiterFilterFactory wordDelimiterFilterFactory = new WordDelimiterFilterFactory();
            HashMap<String, String> args = new HashMap<String, String>();
            args.put("generateWordParts", "1");
            args.put("generateNumberParts", "1");
            args.put("catenateWords", "1");
            args.put("catenateNumbers", "1");
            args.put("catenateAll", "0");
            args.put("luceneMatchVersion", Version.LUCENE_32.name());
            args.put("language", "English");
            args.put("protected", "protected.txt");
            wordDelimiterFilterFactory.init(args);
            ResourceLoader loader = new SolrResourceLoader(null, null);
            wordDelimiterFilterFactory.inform(loader);
            /*List<String> protectedWords = new ArrayList<String>();
            protectedWords.add("good bye");
            protectedWords.add("hello world");
            wordDelimiterFilterFactory.inform(new LinesMockSolrResourceLoader(protectedWords));
            */
            return wordDelimiterFilterFactory.create(stream);
        }
    };
}

输入文本:

你好世界

再见

你对未来的计划是什么?


受保护的字符串:

再见

你好世界


输出:

(你好,startOffset=0,endOffset=5,positionIncrement=1,type=)

(world,startOffset=6,endOffset=11,positionIncrement=1,type=)

(好,startOffset=12,endOffset=16,positionIncrement=1,type=)

(再见,startOffset=17,endOffset=20,positionIncrement=1,type=)

(什么,startOffset=21,endOffset=25,positionIncrement=1,type=)

(是,startOffset=26,endOffset=28,positionIncrement=1,type=)

(你的,startOffset=29,endOffset=33,positionIncrement=1,type=)

(plan,startOffset=34,endOffset=38,positionIncrement=1,type=)

(for,startOffset=39,endOffset=42,positionIncrement=1,type=)

(未来,startOffset=43,endOffset=49,positionIncrement=1,type=)

4

1 回答 1

0

您正在使用至少在空白级别上进行标记的标准标记器,因此您将始终将“hello world”拆分为“hello”和“world”。

TokenStream stream = new StandardTokenizer(Version.LUCENE_32, reader);

请参阅 Lucene 文档:

公共最终类 StandardTokenizer 扩展了 Tokenizer

使用 JFlex 构建的基于语法的分词器

对于大多数欧洲语言文档,这应该是一个很好的标记器:

在标点符号处拆分单词,删除标点符号。但是,后面没有空格的点被视为标记的一部分。

在连字符处拆分单词,除非标记中有数字,在这种情况下,整个标记被解释为产品编号并且不被分割。

将电子邮件地址和 Internet 主机名识别为一个标记。

单词分隔符受保护的单词列表适用于以下内容:

  • ISBN2345677 拆分为 ISBN 2345677
  • text2html 不拆分为 text 2 html(因为 text2html 已添加到受保护的字词中)

如果你真的想做你提到的事情,你可以使用KeywordTokenizer。但是您必须自己完成完整的拆分。

于 2011-07-18T06:37:09.353 回答