1,相似匹配
在网页搜索或电商产品搜索结果页面,很多时候会看到一个相似文档、相似产品或找相似的链接。Solr 使用 MoreLikeThisComponent(MLT)和 MoreLikeThisHandler 实现了一样的功能。如上所述,MLT 是与标准 SolrRequestHandler 集成在一起的;MoreLikeThisHandler 与 MLT 结合在一起,并添加了一些其他选项,但它要求发布一个单一的请求。我将着重讲述 MLT,因为使用它的可能性更大一些。
MLT 要求字段被储存或使用检索词向量,检索词向量以一种以文档为中心的方式储存信息。MLT 通过文档的内容来计算文档中关键词语,然后使用原始查询词语和这些新词语创建一个新的查询。提交新查询就会返回其他查询结果。所有这些都可以用检索词向量来完成:只需将 termVectors="true" 添加到 schema.xml 中的 声明。
2,MoreLikeThis两种实现
第一种:SearchHandler中的MoreLikeThisComponent,MoreLikeThis以组件的身份出现,适于简单应用。
第二种:MoreLikeThisHandler,MoreLikeThis作为一个单独的Handler来处理,可以应用过滤等较复杂操作。
3,参数查询
id,文档主键,或使用其他唯一键;
fl,需要返回的字段
mtl.fl,根据哪些字段判断相似度
mlt.mindf,最小文档频率,所在文档的个数小于这个值的词将不用于相似判断
mlt.mintf,最小分词频率,在单个文档中出现频率小于这个值的词将不用于相似判断mlt.count,返回相似文章个数
需要注意的是 mlt.fl 中的 field 的 termVectors=true 才有效果。
4,第一种solrJ的实现
HttpSolrClient solrServer = SolrServer.getServer();
SolrQuery query = new SolrQuery();
List articles = new ArrayList();
try {
query.setQuery("id:" + id)
.setParam("fl", "id,title,brand_s")
.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;
SimpleOrderedMap mltResults = (SimpleOrderedMap) 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;// 排除本身
ProductBO article = new ProductBO();
article.setId(idStr);
article.setTitle(doc.getFieldValue("title").toString());
article.setBrand_s(doc.getFieldValue("brand_s").toString());
articles.add(article);
}
}
5,第二种solrJ实现
配置MoreLikeThisHandler,修改solrconfig.xml
在最后一个requestHandler下新增/mlt
SolrQuery query = new SolrQuery(); // 指定配置的RequestHandler,默认使用/select
query.setRequestHandler("/mlt");
List articles = new ArrayList();
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");
query.addFilterQuery("status:" + Article.STATUS_PUBLISHED);
query.setRows(count);// mlt.count无效,需要此方法控制返回条数
QueryResponse response = solrServer.query(query);
if (response == null) return articles;