問題一: 測試人員告訴我數字不能被搜索。因而開始找緣由:
<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的管理界面看能發現點啥?ide
終於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;
}
測試