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;
	}



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM