本文是针对在学习和运用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文件夹中的文件。