本文是針對在學習和運用solr6.0中遇到的問題做總結,會持續更新
配置solr 404問題
在Solr 6.0 學習(一)環境搭建中很多同學在評論區說404問題
訪問:http://localhost:8080/solr/index.html 正常
訪問:http://localhost:8080/solr 報404
我們看下到web.xml中部分配置如下:
<servlet>
<servlet-name>LoadAdminUI</servlet-name>
<servlet-class>org.apache.solr.servlet.LoadAdminUiServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoadAdminUI</servlet-name>
<url-pattern>/index.html</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
我們看到web.xml中配置了歡迎頁爲什麼還會報404呢?
如上配置中,我們找到這個org.apache.solr.servlet.LoadAdminUiServlet,查看其源碼
public final class LoadAdminUiServlet extends BaseSolrServlet
{
public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
response.addHeader("X-Frame-Options", "DENY");
/*
當訪問是http://localhost:8080/solr的時候
admin變量值是"/",是找不到的
*/
final String admin = request.getRequestURI().substring(request.getContextPath().length());
final CoreContainer cores = (CoreContainer)request.getAttribute("org.apache.solr.CoreContainer");
final InputStream in = this.getServletContext().getResourceAsStream(admin);
if (in != null && cores != null) {
try {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html");
final Writer out = new OutputStreamWriter((OutputStream)response.getOutputStream(), StandardCharsets.UTF_8);
final String html = IOUtils.toString(in, "UTF-8");
final Package pack = SolrCore.class.getPackage();
final String[] search = { "${contextPath}", "${adminPath}", "${version}" };
final String[] replace = { StringEscapeUtils.escapeJavaScript(request.getContextPath()), StringEscapeUtils.escapeJavaScript("/admin/cores"), StringEscapeUtils.escapeJavaScript(pack.getSpecificationVersion()) };
out.write(StringUtils.replaceEach(html, search, replace));
out.flush();
}
finally {
IOUtils.closeQuietly(in);
}
}
else {
response.sendError(404);
}
}
}
處理辦法:
將LoadAdminUI這個servlet的映射關係屏蔽掉即可。
自定查詢組件問題
在Solr 6.0 學習(十五)Solr SearchComponent)
solrconfig.xml中的配置
<searchComponent name="customer" class="com.component.CustomerComponent" ></searchComponent>
將查詢組件配置到requestHandler下
<requestHandler name="/select" class="solr.SearchHandler">
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int>
<str name="df">text</str>
</lst>
<arr name="components">
<str>customer</str>
</arr>
</requestHandler>
再訪問solr的時候發現沒有數據返回。
我看到當自定義查詢組件的時候就不會加載默認組件
/*
*獲取默認查詢組件
*/
protected List<String> getDefaultComponents() {
final ArrayList<String> names = new ArrayList<String>(8);
names.add("query");
names.add("facet");
names.add("facet_module");
names.add("mlt");
names.add("highlight");
names.add("stats");
names.add("debug");
names.add("expand");
return names;
}
我們嘗試將query組件添加
<arr name="components">
<str>customer</str>
<str>query</str>
</arr>
再次訪問,數據正常返回。
補充:其他組件也是一樣,如facet
IK分詞
在Solr 6.0 學習(三)中我們看到如下配置:
<!-- IK分詞 start-->
<fieldType name="text_ik" class="solr.TextField">
<analyzer type="index">
<!--
IKTokenizerFactory:繼承 TokenizerFactory
useSmart:是否啓用 智能分詞
-->
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" />
<!--
StopFilterFactory:停止分詞,會根據stopwords.txt中配置的文件停止分詞
-->
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
</analyzer>
<analyzer type="query">
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true" />
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
</analyzer>
</fieldType>
<!-- IK分詞 end-->
什麼是智能分詞?看了源碼知道,其實IK作者的說法:
非智能分詞:細粒度輸出所有可能的切分結果
智能分詞: 合併數詞和量詞,對分詞結果進行歧義判斷
我們看看具體的例子,詞條:小貓小豬小狗
非智能分詞:
0 - 2 : 小貓 | CN_WORD
0 - 1 : 小 | CN_WORD
1 - 2 : 貓 | CN_CHAR
2 - 4 : 小豬 | CN_WORD
2 - 3 : 小 | CN_WORD
3 - 4 : 豬 | CN_CHAR
4 - 6 : 小狗 | CN_WORD
4 - 5 : 小 | CN_WORD
5 - 6 : 狗 | CN_CHAR
智能分詞:
0 - 2 : 小貓 | CN_WORD
2 - 4 : 小豬 | CN_WORD
4 - 6 : 小狗 | CN_WORD
分詞的結果依賴於我們分詞的詞庫
加載配置文件
我們在使用SolrResourceLoader加載配置文件的時候,如
SolrResourceLoader loader = new SolrResourceLoader(null);
loader.openResource(fileName);
實際上這個配置文件是在特定的路徑下的。
路徑爲:core的同級目錄下conf文件夾中的文件。