solr 相似查询 -- MoreLikeThis

2019-03-27 01:17|来源: 网路

在 Google上尝试一个查询,您会注意到每一个结果都包含一个 “相似页面” 链接,单击该链接,就会发布另一个搜索请求,查找出与起初结果类似的文档。Solr 使用MoreLikeThisComponent(MLT)和 MoreLikeThisHandler实现了一样的功能。如上所述,MLT 是与标准 SolrRequestHandler集成在一起的;MoreLikeThisHandler与 MLT 结合在一起,并添加了一些其他选项,但它要求发布一个单一的请求。我将着重讲述 MLT,因为使用它的可能性更大一些。幸运的是,不需要任何设置就可以查询它,所以您现在就可以开始查询。您可以向请求添加很多 HTTP 查询参数,并且大部分参数都有智能的默认值,因此我将着重讲述使用 MLT 必须了解的参数。

MoreLikeThisComponent参数:
参数                                          说明                                                                               值域
mlt                  在查询时,打开 / 关闭 MoreLikeThisComponent的布尔值。      真 | 假
mlt.count       可选。每一个结果要检索的相似文档数。                                            > 0
mlt.fl               用于创建 MLT 查询的字段。                              模式中任何被储存的或含有检索词向量的字段。

mlt.maxqt      可选。查询词语的最大数量。由于长文档可能会有很多关键词语,

                       这样 MLT 查询可能会很大,从而导致反应缓慢或可怕的 

                       TooManyClausesException,该参数只保留最关键的词语。           > 0

说明:MLT要求字段被储存或使用检索词向量,检索词向量以一种以文档为中心的方式储存信息。MLT通过文档的内容来计算文档中关键词语,然后使用原始查询词语和这些新词语创建一个新的查询。提交新查询就会返回其他查询结果。所有这些都可以用检索词向量来完成:只需将 termVectors="true"添加到 schema.xml 中的 <field>声明。

尝试下面的样例查询,然后检查返回结果中的 moreLikeThis部分:

1. 在URL中输入:
http://localhost:8080/solr/select/?q=*%3A*&mlt=true&mlt.mindf=1&mlt.mintf=1 &mlt.fl=name&fl=id%2C+name&mlt.count=3

结果如下:


2. 对应在java代码中写入:


结果如下:


相关说明:
(1)查询参数:
id,文档主键,或使用其他唯一键;
fl,需要返回的字段
mtl.fl,根据哪些字段判断相似度
mlt.mindf,最小文档频率,所在文档的个数小于这个值的词将不用于相似判断
mlt.mintf,最小分词频率,在单个文档中出现频率小于这个值的词将不用于相似判断
mlt.count,返回相似文章个数
(2)如果setQuery中的查询条件,不是唯一结果,是多个文章,那么程序中会得到每个文章对应的moreLikeThis列表。
(3)如果遇到org.apache.solr.search.EarlyTerminatingCollectorException,则将返回条数count设置为1即可。
(4)若需根据id返回文章列表,可参考如下代码:

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;
    }
}



转自:http://blog.csdn.net/qiruiduni/article/details/38730439

相关问答

更多
  • 您始终可以使用mlt fq=cat:50f05b1506345aa8d过滤查询 例如 > http://myhost/collection1/mlt?q=id:50fd1dd80364e49234543b3b2807ef&fq=cat:50f05b1506345aa8d&wt=xml&fl=id,text,cat You can always use filter query with mlt fq=cat:50f05b1506345aa8d e.g. > http://myhost/collection ...
  • 恐怕不是开箱即用的。 可能会比较两个tsvector以确定它们是否足够相似,或者拉出前n个相似的tsvector,但是没有现成的功能来执行此操作。 好消息是,既然tsvectors支持GIN索引,那么复杂的部分就完成了。 我认为你需要做的是在C中创建一个函数,它确定两个tsvector的交集。 从那里你可以创建一个函数来确定它们是否重叠以及解决这个问题的操作符。 从这里开始,根据最大重叠度创建排名应该不会太难。 当然,我怀疑这对C语言来说最容易做到,但如果需要的话,你也可以使用其他过程语言。 关于Postg ...
  • 据我所知,更喜欢这个处理程序只是单个分片,因此它只会考虑本地分片中可用的文档。 更像是这个查询解析器确实提到它是Solr Cloud感知的,所以请尝试使用它。 MLTQParser允许检索与给定文档类似的文档。 它使用Lucene现有的MoreLikeThis逻辑,也可以在SolrCloud模式下工作。 此处使用的文档标识符是唯一的id值,而不是Lucene内部文档ID。 返回的文档列表不包括查询的文档。 查找文档,如id = 1的文档,并使用名称字段进行相似性。 {!mlt qf=name}1 使用min ...
  • 你可以用文档的全部内容创建一个查询,通过QueryParser运行它,如下所示: QueryParser myQueryParser = new QueryParser(myFieldName, new StandardAnalyzer()); Query query = myQueryParser.parse(QueryParserBase.escape(myDoc.get(myFieldName))); 潜在的问题将是过长的查询导致性能不佳(这就是为什么MoreLikeThis试图选择最佳查询条件而不 ...
  • 所以,经过一番调查后我能够发现问题。 我们意外地将所有文档更新为相同的内容(所有字段都相同),然后SOLR很难工作:) so, after some investigation I was able to find the problem. We accidentally updated all documents to the same content (all fields were equal) and then it was quite difficult for SOLR to work :)
  • 简短的回答是NO,你需要在这样的架构更改后重新索引。 启用术语向量将加速从原始输入文档中找到有趣术语的过程(如果此文档在索引中)。 第二阶段计时(当更多像这个查询发生时)将保持不变。 有关MLT如何工作的更多信息[1]。 通常,在对架构应用此类更改时,需要重新索引文档以使Solr构建相关的数据结构(术语向量是每个文档的迷你索引,并且需要将特定文件存储在磁盘上[2]注意这会增加你的磁盘利用率) [1] https://www.slideshare.net/AlessandroBenedetti/advance ...
  • 这样做的一种方式是在fq中使用连接查询,并且它也适用于MLT。 就像是: &fq =(!从=位置连接到=位置)DocumentID:1234 One way of doing this would be using join query in fq and it works for MLT as well. Something like: &fq=(!join from=location to=location)DocumentID:1234
  • 经过大量的实验,浏览网页并深入了解Solrj API后,我提出了以下解决方案。 可能有更好的方法,我真的很想知道。 首先从响应中提取moreLikeThis部分并将其转换为NamedList : NamedList mlt = (NamedList) queryResponse.getResponse().get("moreLikeThis"); 在调试时检查NamedList mlt ,它显示AZ133007条目以及'moreLikeThis'的SolrDocuments。 { AZ133007 ...
  • 更多像这需要存储的唯一密钥。 MoreLikeThis requires a stored unique key.
  • Mlt boost似乎不受支持。 您可以查看Mlt Sort Patch SOLR-1545 Mlt boost does not seem to be supported. You can probably check the Mlt Sort Patch SOLR-1545