在solr中有两种方式实现MoreLikeThis:
第一种:SearchHandler中的MoreLikeThisComponent,MoreLikeThis以组件的身份出现,适于简单应用。
第二种:MoreLikeThisHandler,MoreLikeThis作为一个单独的Handler来处理,可以应用过滤等较复杂操作。
本文给出针对第一种的solrj实现代码,如果想对结果进行过滤,等获取到结果之后在程序中过滤掉即可,缺点是相关文档数不固定。
代码如下:
import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.util.SimpleOrderedMap; import base.util.ConfigUtil; import demo.bean.Article; public class SolrService { private static Logger log = Logger.getLogger(SolrService.class); private static HttpSolrServer solrServer; static { solrServer = new HttpSolrServer(ConfigUtil.getValue("solr.url")); solrServer.setConnectionTimeout(5000); } /** * 根据文章标题查相关文章。 * * @param id 指定文章(文档)id * @param count 返回条数 * @return 相关文章对象列表 */ public static List<Article> getRelated(int id, int count) { SolrQuery query = new SolrQuery(); List<Article> articles = new ArrayList<Article>(); try { query.setQuery("id:" + id) .setParam("fl", "id,title,score") .setParam("mlt", "true") .setParam("mlt.fl", "title") .setParam("mlt.mindf", "1") .setParam("mlt.mintf", "1") .setParam("mlt.count", String.valueOf(count)); QueryResponse response = solrServer.query(query); if (response == null) return articles; @SuppressWarnings("unchecked") SimpleOrderedMap<SolrDocumentList> mltResults = (SimpleOrderedMap<SolrDocumentList>) response.getResponse().get("moreLikeThis"); for (int i = 0; i < mltResults.size(); i++) { SolrDocumentList items = mltResults.getVal(i); for (SolrDocument doc : items) { String idStr = doc.getFieldValue("id").toString(); if (StringUtils.equals(idStr, id+"")) continue;// 排除本身 Article article = new Article(); article.setId(Integer.parseInt(idStr)); article.setTitle(doc.getFieldValue("title").toString()); articles.add(article); } } } catch (Exception e) { log.error("从solr获取相关新闻时遇到错误", e); } return articles; } }
相关说明:
1,查询参数:
id,文档主键,或使用其他唯一键;
fl,需要返回的字段
mtl.fl,根据哪些字段判断相似度
mlt.mindf,最小文档频率,所在文档的个数小于这个值的词将不用于相似判断
mlt.mintf,最小分词频率,在单个文档中出现频率小于这个值的词将不用于相似判断
mlt.count,返回相似文章个数
2,如果setQuery中的查询条件,不是唯一结果,是多个文章,那么程序中会得到每个文章对应的moreLikeThis列表。
3,如果遇到org.apache.solr.search.EarlyTerminatingCollectorException,解决方案参见链接文章。
参考文档: