Solr 自定义FieldType Analyzer不生效 有关问题查找
Solr 自定义FieldType Analyzer不生效 问题查找
最近做得一个项目,需要实现字段的拼音搜索功能,在schema配置了一个fieldtyp,如下:
<fieldType name="cn_pinyin" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true" omitNorms="true" omitPositions="false"> <analyzer type="index"> <tokenizer class="solr.PatternTokenizerFactory" pattern=",\s*" /> <filter class="solr.NGramFilterFactory" minGramSize="1" maxGramSize="7" /> <filter class="solr.StandardFilterFactory"/> <filter class="solr.TrimFilterFactory"/> <filter class="com.dfire.tis.solrextend.fieldtype.pinyin.PinyinTokenFilterFactory" /> </analyzer> <analyzer type="query"> <tokenizer class="solr.PatternTokenizerFactory" pattern=",\s*" /> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> </fieldType>
在analyzer的index部分配置了tokenizer及一系列filter过滤器来处理输入的字段值,先有逗号分隔成标题单元,然后对每个标题单元进行N元分词,然后对标题单元作左右去除空格,最后使用自定义的PinyinTokenFilterFactory进行中文分词,分词结果为中文和拼音的分词结果,都会生成到term列表中。
最后将这段配置发布到线上之后,并没有得到预想的结果。经过实际测试发现连逗号分割的标准PatternTokenizerFactory分词器也没有生效。尝试了好多办法都没有解决,耽搁了好久,最后发现全量build中心的一段代码有问题:
public static IndexWriter createRAMIndexWriter(IndexConf indexConf) throws IOException { RAMDirectory ramDirectory = new RAMDirectory(); IndexWriterConfig indexWriterConfig = new IndexWriterConfig( new StandardAnalyzer() ); indexWriterConfig.setMaxBufferedDocs(Integer.MAX_VALUE); indexWriterConfig .setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH); indexWriterConfig.setOpenMode(OpenMode.CREATE); IndexWriter addWriter = new IndexWriter(ramDirectory, indexWriterConfig); addWriter.commit(); return addWriter; }
在build中心的代码中有一个创建indexwriter实例的方法,发生问题的代码是构建IndexWriterConfig实例的代码部分,创建IndexWriterConfig实例的时候在构造函数上新创建了StandardAnalyzer对象,这是发生问题的根源,也就是告诉indexWriter,索引的时候调用到的field的analyzer引用全部都使用标准的StandardAnalyzer对象,所以就解释了之前在schema中配置的cn_pinyin中的analyzer统统没有生效的现象了。
正确的代码应该是这样的:
IndexWriterConfig indexWriterConfig = new IndexWriterConfig( schema.getIndexAnalyzer() );
这样就正确了。
这次bug的发生真是验证了那句话,牵一发而动全身呀,对代码我们应该有敬畏之心。