【问题标题】:Solr Custom RequestHandler - optimizing resultsSolr Custom RequestHandler - 优化结果
【发布时间】:2011-12-14 07:43:17
【问题描述】:

又一个可能令人尴尬的问题。请随时指出任何可能被忽略的明显解决方案 - 我之前搜索过解决方案但一无所获,但有时是选择了错误的关键字进行搜索。
情况如下:几个月前为企业系统编写了我自己的 RequestHandler,以便在对 solr 核心进行的所有查询中注入一些必要的安全参数作为额外的过滤器。一切顺利进行,直到收集查询索引产生的文档然后返回给用户的部分。

基本上在创建过滤器并执行查询之后,我们会得到一组文档 ID(和分数),但随后我们必须遍历 ID 以构建结果集,一次一个命中 - 这比查询标准请求处理程序慢 10 倍,而且随着结果数量的增加,只会变得更糟。更糟糕的是,由于我们的模式在很大程度上依赖于动态字段以获得灵活性,因此(据我所知)没有办法(据我所知)以前检索要检索每个文档的字段列表,除了测试每个文档的所有可能组合。

以下代码是在生产中运行的代码的简化版本,用于查询 SolrIndexSearcher 并构建响应。

事不宜迟,我的问题是:

  • 有什么方法可以一次检索所有结果,而不是按文档构建响应文档?
  • 是否有可能获取每个结果的字段列表,而不是测试所有可能的组合?
  • 我应该注意此代码中的任何特定 WTF?随意踢我!
//function that queries index and handles results
private void searchCore(SolrIndexSearcher searcher, Query query, 
        Filter filter, int num, SolrDocumentList results) {  

    //Executes the query
    TopDocs col = searcher.search(query,filter, num);

    //results
    ScoreDoc[] docs =  col.scoreDocs;        

    //iterate & build documents
    for (ScoreDoc hit : docs) {
        Document doc = reader.document(hit.doc);
        SolrDocument sdoc = new SolrDocument();

        for(Object f : doc.getFields()) {
            Field fd = ((Field) f);

            //strings
            if (fd.isStored() && (fd.stringValue() != null))
                sdoc.addField(fd.name(), fd.stringValue());
            else if(fd.isStored()) {
                //Dynamic Longs
                if (fd.name().matches(".*_l") ) {
                    ByteBuffer a = ByteBuffer.wrap(fd.getBinaryValue(), 
                            fd.getBinaryOffset(), fd.getBinaryLength());
                    long testLong = a.getLong(0);
                    sdoc.addField(fd.name(), testLong );
                }
                //Dynamic Dates
                else if(fd.name().matches(".*_dt")) {
                    ByteBuffer a = ByteBuffer.wrap(fd.getBinaryValue(), 
                        fd.getBinaryOffset(), fd.getBinaryLength());
                    Date dt = new Date(a.getLong());
                    sdoc.addField(fd.name(), dt );
                }
                //...
            }                 
        }
        results.add(sdoc);
    }
}  

【问题讨论】:

  • 为澄清起见,您创建此自定义 RequestHandler 的唯一目的是为每个请求添加一个额外的过滤器。对吗?
  • @rfeak - 简短的回答,是的。是否相关?你有什么不同的建议吗?
  • 是的。如果我没记错的话(已经 2 年了),有一些方法可以在添加到每个查询的 XML 文件中添加默认过滤器。然后默认过滤器像其他过滤器一样缓存在 FilterCache 中。它们与其他过滤器的聚合应该非常快,您不必获取文档来应用过滤器。不确定您是否考虑过这种方法。
  • @rfeak 我认为这有可能很棒。 =) 去试一试,结果会告诉你的。

标签: solr full-text-search requesthandler


【解决方案1】:

每个 OP 请求:

虽然这不能回答您的具体问题,但我建议您使用另一种方法来解决您的问题。

要向所有查询添加过滤器,您可以在 SolrConfig.xml 文件中的 StandardRequestHandler 中添加“附加”部分。添加一个“fl”(代表过滤器)部分并添加您的过滤器。通过 StandardRequestHandler 传送的每个请求都会自动附加过滤器。

此过滤器与其他过滤器一样被处理,因此它被缓存在 FilterCache 中。结果是在查询时进行了相当快的过滤(通过 docIds)。这可以让您避免必须在解决方案中提取单个文档来应用过滤条件。

【讨论】:

    猜你喜欢
    • 2011-09-05
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多