zoukankan      html  css  js  c++  java
  • Solr 数字字符不能搜索的一个问题

    问题一: 测试人员告诉我数字不能被搜索。于是开始找原因:

    <fields>
    ***
    <field name="productName" type="text" indexed="true" stored="true" />
    ***
    </fields>

    fieldType text配置:
    <fieldType name="text" class="solr.TextField" positionIncrementGap="100">
       <analyzer type="index">
      <tokenizer class="solr.LowerCaseTokenizerFactory"/>
      <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="50" side="front"/>
       </analyzer>
       <analyzer type="query">
      <tokenizer class="solr.LowerCaseTokenizerFactory"/>
      <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="50" side="front"/>
       </analyzer>
    </fieldType>

    当我的productName中包含数字字符的时。比如有个产品的名字叫 ‘嘎嘎噶123’ 那么用数字1/2/3/12等等都不能搜索到

    当时‘123嘎嘎噶’时也是一样。找了好久没有找到原因。也不知道怎么去找这个原因。于是边问喷油。猜想是分词的问题。于是边看Solr的管理界面看能发现点啥?

    终于QQ群里一哥们说 solr.LowerCaseTokenizerFactory 会过滤掉数字  在Solr的Analysis 菜单下 看到了可以进行分词的演示正对当前的schema.xml配置。还可以选择相应的 field  一试 果真是LowerCaseTokenizerFactory 这个家伙的问题。于是寻找替代方案。经过尝试与搜索。下面的配置

    最终解决了数字不能被搜索的问题。(相应的属性也改为此类型)

    <fieldType name="text_inclunum" class="solr.TextField" positionIncrementGap="100">
      <analyzer type="index">
     <tokenizer class="solr.WhitespaceTokenizerFactory"/>
     <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="50" side="front"/>
      </analyzer>
      <analyzer type="query">
     <tokenizer class="solr.WhitespaceTokenizerFactory"/>
     <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="50" side="front"/>
      </analyzer>
    </fieldType>


     由于我们库里的产品有拼音字段。而且是大写。 如果我用AMXL 搜索 能搜到相应的拼音。进而搜索相应的产品阿莫西林。(solr配置了all查询。拼音字段copy到了all中。)

    可如果我用amxl搜索则不能搜到。于是我在程序中solr的查询语句时把查询值toUpperCase(); 终于解决了小写字母不能搜索的问题。


    问题二:

    但第二天发现引入的了新的问题。如果一个产品是 ‘d阿莫西林’ 那么我用d阿莫西林 进行搜索,将不能把 'd阿莫西林'这个产品搜出来。开始不知道为啥,放到Solr的Analysis中一测。发现了。我程序把它变为 ‘D阿莫西林’ 进行查询了。但SOlr中搜索的却是'd阿莫西林 ' ,这次所有已小写字母打头的产品。如果用产品全名如‘‘d阿莫西林’进行搜索(自动补全出来的),将不能搜索出来。


    解决了数字的问题。又遇到了小写字母的问题。 这次没有找到个Solr这边的方案。于是打算修改程序。 思路就是 把程序中SOlr的查询值变大写的地方改为。如果查询的值中有中文则不变大写。如果没有则变大写。

    这样的话。如果产品是有数字的,或者有小写字母的 都能被搜索出来。 全字母的也能根据拼音搜索出来。("solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="50")这个就是从左到右一个一个分词的。

    于是 网上搜索一个正则查找字符串中是否有中文:

     

        /**
                 * 判断一个字符串中是否含有中文
                 * @param str
                 * @return
                 */
                public static boolean isContainsChinese(String str)     
                {    
                    Matcher matcher = Pattern.compile("[u4e00-u9fa5]").matcher(str);
                    boolean flg = false;  
                    if (matcher.find())    {    
                        flg = true;   
                    }     
                    return flg;     
                }  
         
            public static String toUpperOrNot(String temp)
            {
                if (temp == null)
                    return "";
                if(StringUtils.isContainsChinese(temp))
                {
                    return temp;
                }else
                {
                    return temp.toUpperCase();
                }
            }


    于是在SOLR查询值的地方调用下toUpperOrNot()即可。最好调用下下面的转义。



    温馨提示: Solr查询中如果查询值中有特殊字符需要转义:

        public static final String    NEAD_TO_CONVERT_CHAR    = "([/:()!])";    
            // solr query need to convert meaning
            public static String convertMeaningChar(String temp)
            {
                if (temp == null)
                    return "";
                temp = temp.replaceAll(NEAD_TO_CONVERT_CHAR, "\\$1");
                return temp;
            }

  • 相关阅读:
    mysql初始化/usr/local/mysql/bin/mysqld: error while loading shared libraries: libnuma.so.1: cannot open shared object file: No such file or directory
    centos重启出现type Control-D to continue【fsck使用】
    find 常用命令
    保持简单----纪念丹尼斯•里奇(Dennis Ritchie)
    最有效的五个方法,彻底控制你的负面情绪,你有吗
    ERROR 1366 (HY000): Incorrect string value: 'xE9x83x91xE5xB7x9E' for column 'aa' at row 1 MySQL 字符集
    Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'
    mysql从5.6升级到5.7后出现 Expression #1 of ORDER BY clause is not in SELECT list,this is incompatible with DISTINCT
    mysqld_safe error: log-error set to '/data/log/mysqld.log', however file don't exists. Create writable for user 'mysql'.The server quit without updating PID file (/data/mysql/mysqld.pid)
    ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
  • 原文地址:https://www.cnblogs.com/cuihongyu3503319/p/11665919.html
Copyright © 2011-2022 走看看