`
mozhenghua
  • 浏览: 324413 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Solr分词fieldType分词解析器设置错误导致查询错误

    博客分类:
  • solr
阅读更多

      今天在线上生产环境中碰到一个Solr的查询条件无法匹配到查询结果的问题,问题虽小,但是找到问题的过程确实比较周折,还好最终问题只是一层窗户纸,这里记录以下,以作备忘。

       问题是这样的,业务方告诉我有一个查询条件,没有办法匹配到目标记录。查询条件是:name:Y9砵仔糕吕托 收到问题,于是就开始了我的排错之路。

        首先,确认了一下name字段原始的文本字段是“Y9砵仔糕吕托”,对应的列的名称是 name,field type是一个自定义类型,类型为:

 

 <fieldType name="like" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="false" omitNorms="true" omitPositions="true">
      <analyzer type="index">
        <tokenizer class="solr.PatternTokenizerFactory" pattern=",\s*"/>
        <filter class="com.dfire.tis.solrextend.fieldtype.pinyin.AllWithNGramTokenFactory"/>
        <filter class="solr.StandardFilterFactory"/>
        <filter class="solr.TrimFilterFactory"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.PatternTokenizerFactory" pattern=",\s*"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>

 这个filetype为了实现用户在搜索引擎上实现类似数据like查询的需求(当然solr上也能使用wildcardQuery,但是wildcardQuery比较耗费性能,数据量小应该没有问题,数据量大的话就要斟酌一下了)。

 

 

   AllWithNGramTokenFactory这个filter类型扩展了一下Solr默认的NGram类型,在分析的时候额外多加了一个整个field的字面量作为Term语汇单元。

     为了排查问题,先写了一个小程序,打印一下索引文件上name 字段term为“Y9砵仔糕吕托” 的记录到底存在不存在,写了以下一段代码:

private void readIteraveTerm() throws Exception {
        EmbeddedSolrServer server ;
		SolrCore core = server.getCoreContainer().getCore("supplygood");
		IndexReader rootreader = core.getSearcher().get().getIndexReader();
		LeafReader reader = null;
		Terms terms = null;
		TermsEnum termEnum = null;
		PostingsEnum posting = null;

		BytesRef term = null;
		int docid = 0;
		for (LeafReaderContext leaf : rootreader.getContext().leaves()) {
			reader = leaf.reader();
			liveDocs = reader.getLiveDocs();
			terms = reader.terms("name");

			termEnum = terms.iterator();
			int count = 0;
			String find = "Y9砵仔糕吕托";

			if ((termEnum.seekExact(new BytesRef(find)))) {

				System.out.println(termEnum.term().utf8ToString());
				posting = termEnum.postings(posting);
				do {

					docid = posting.nextDoc();
					System.out.println("docid:" + ("" + docid) + "_" + leaf.docBase);
				} while (docid != PostingsEnum.NO_MORE_DOCS);	
			}
		}
	}

 这段代码的执行结果证明,在索引上Y9砵仔糕吕托”为Term的记录是存在,那奇怪的是为什么,通过查询条件 name:Y9砵仔糕吕托 找不到对应的记录呢?

 

   又想起调试一下Solr的代码,最终底层Lucene是会通过 TermQuery这个类来执行查询的:

package org.apache.lucene.search;

public class TermQuery extends Query {
  .....
  public TermQuery(Term t) {
    term = Objects.requireNonNull(t);
    perReaderTermState = null;
  }
}

 所以在TermQuery类的构造函数上加了一个调试断点,启动程序进行条件,看看构造函数上传入的参数Term到底是一个什么值,结果看到的构造函数参数为“y9砵仔糕吕托”,奇怪,怎么大写的Y变成小写了。然后通过“y9砵仔糕吕托”到索引上找果然是没有这个Term作为的记录的,然后再看了一下Schema的fieldType,果然在query的分析配置中有<filter class="solr.LowerCaseFilterFactory"/>这个配置项,也就是说在查询阶段,会将name列中含有的大写字母统统转化成小写字母,而在索引生成的时候并没有做这大写转小写的操作,所以很自然的就会发生本文一开头说的问题。

  将FiledType改成下面这个样子就好了:

  <fieldType name="like" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="false" omitNorms="true" omitPositions="true">
      <analyzer type="index">
        <tokenizer class="solr.PatternTokenizerFactory" pattern=",\s*"/>
        <filter class="com.dfire.tis.solrextend.fieldtype.pinyin.AllWithNGramTokenFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.TrimFilterFactory"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.PatternTokenizerFactory" pattern=",\s*"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>

 在analyzer中也加了一个<filter class="solr.LowerCaseFilterFactory"/>过滤器问题就解决了,哈哈酷

 

 

分享到:
评论

相关推荐

    solr分词器使用手册

    ### Solr分词器使用手册知识点详解 #### 一、Solr概述 - **定义**:Solr是一款基于Java开发的、由Apache基金会维护的顶级开源项目,它是一款高性能的全文检索服务器。Solr不仅继承了Lucene的核心索引与搜索能力,还...

    solr ik分词器

    Solr是中国最流行的开源搜索引擎平台之一,而IK Analyzer是一款针对中文的高性能分词器,尤其在处理现代汉语的复杂情况时表现出色。本教程将详细解释如何在Solr中安装和使用IK分词器。 首先,让我们理解一下什么是...

    solr中文分词器

    Solr中文分词器是针对Apache Solr全文检索引擎在处理中文文本时的不足而设计的一种解决方案。Solr默认的分词策略主要针对英文文本,它以空格为分隔符进行分词,而对于中文这种没有明显分隔符的语言,就需要特定的...

    k-analyzer-solr solr分词器

    Solr分词器是搜索引擎Apache Solr中的一个重要组件,它负责对输入的文本进行分析,将其拆分成可索引的基本单元——词语。"k-analyzer-solr" 是一个特定的分词器实现,用于优化Solr的文本处理流程。在Solr中,分词器...

    solr中文分词高版本

    描述中提到的“网上提供的solr中文分词器大多不支持6.5以上,会报错”,这通常是因为Solr的升级引入了新的API或改变了某些功能,导致旧版的分词器与新版本不兼容。报错的具体信息虽然没有给出,但常见的问题可能包括...

    Solr分词项目工程实例

    1. 配置索引:在Solr配置文件中定义字段类型(field type),指定对应的分词器和过滤器。 2. 导入数据:使用Solr的DataImportHandler(DIH)从数据库或其他数据源导入数据。 3. 分词索引:Solr会自动对导入的数据...

    IK分词solr5.0.0

    2. **修改schema.xml**:在Solr的配置文件schema.xml中,我们需要定义一个或多个字段类型(fieldType),并指定使用IK分词器。例如,可以创建一个名为`text_ik`的字段类型,配置如下: ```xml &lt;fieldType name=...

    solr 5.x 和 6.x 最新中文分词器

    通常在`schema.xml`或`managed-schema`中定义字段类型(FieldType),并设置对应的分词器。例如,使用IK Analyzer: ```xml &lt;fieldType name="text_ik" class="solr.TextField"&gt; &lt;analyzer type="index"&gt; ...

    Solr-ik分词

    2. 在Solr的schema.xml文件中,定义一个字段类型(FieldType),指定使用Ik分词器。例如: ```xml &lt;fieldType name="text_ik" class="solr.TextField" positionIncrementGap="100"&gt; &lt;analyzer type="index"&gt; ...

    solr分词器IKAnalyzer

    **Solr分词器IKAnalyzer详解** Solr是一款强大的全文搜索引擎服务器,而IKAnalyzer是针对中文的开源分词器,广泛应用于Solr和Elasticsearch等搜索引擎中。IKAnalyzer的设计目标是提供一个灵活且易扩展的中文分词...

    solr中文分词jar包ik-analyzer 含class配置 ik-analyzer-7.5.0

    1. **下载与解压**:获取ik-analyzer-7.5.0.jar文件,解压缩后将jar包放入Solr的lib目录下,确保Solr运行时能加载到该分词器。 2. **配置Solr schema.xml**:在Solr的schema.xml文件中,定义字段类型(fieldType),...

    solr 中文分词

    要在 Solr 中使用 IK Analyzer,首先需要将其添加到 Solr 的类路径中,然后在 Solr 的 schema.xml 或 managed-schema 文件中配置字段类型(fieldType),指定使用 IK Analyzer。同时,可以设置自定义词典路径,以...

    支持solr5.5 solr6.0中IK分词需要的资料

    标题和描述提到的是针对Solr 5.5和Solr 6.0版本的IK分词器支持的相关资料,这意味着这些资源可能包括配置文件、文档、示例代码或者更新日志,帮助用户在这些特定版本的Solr中集成和优化IK分词器。 首先,让我们来看...

    solr7.x-ik分词器亲测可用.zip

    "solr7.x-ik分词器亲测可用.zip" 文件是一个包含针对 Solr 7.x 版本优化的 IK 分词器的压缩包,IK(Intelligent Chinese Analyzer)是广泛使用的中文分词库,专为处理中文文本而设计。这个亲测可用的版本意味着已经...

    solr导入 IK分词

    在Solr的`schema.xml`文件中,我们需要定义字段类型(fieldType)来指定使用IK分词器。添加如下配置: ```xml &lt;fieldType name="text_ik" class="solr.TextField" positionIncrementGap="100"&gt; &lt;analyzer type=...

    solr7 的 ik分词器

    2. **修改配置**:编辑`schema.xml`文件,将`&lt;fieldType&gt;`元素中的`analyzer`属性设置为`&lt;analyzer type="index"&gt;`和`&lt;analyzer type="query"&gt;`,指定使用IK分词器。 3. **重启Solr**:完成配置后,重启Solr服务,使...

    solr中文解析器以及使用文档

    然后,在schema.xml中定义字段类型(fieldType),并设置该类型的分析器为IK Analyzer。 4. **自定义词典**:IK Analyzer允许用户自定义词典,以满足特定领域的搜索需求。例如,可以添加行业术语或公司名,确保它们...

    支持solr 5.3.0的IKAnalyzer中文分词器

    IKAnalyzer中文分词器本身已经不支持最新的solr 5,集成到solr中分词会报错,这里将解决了solr 5支持问题的最新IK包共享出来,希望能帮到各位! 附上IK在schema.xml中的配置: &lt;fieldType name="text_ik" class=...

    solr6.0中IK分词需要的资料

    2. **配置文件**:IK分词器的配置文件通常包括`IKAnalyzer.cfg.xml`,这个文件用于设置分词器的行为,比如选择运行模式、启用扩展词典等。用户可以根据实际需求对这个配置文件进行修改。 3. **搜狗词库**:搜狗词库...

Global site tag (gtag.js) - Google Analytics