2011-12-12 49 views
0

另一个潜在的令人尴尬的问题。请随时指出可能被忽略的任何明显的解决方案 - 我之前已经搜索过解决方案,但什么也没找到,但有时候是选择错误的关键字来搜索的问题。
以下是这种情况:几个月前为一个企业级系统编写了我自己的RequestHandler,以便在对solr内核进行的所有查询中插入一些必要的安全参数作为额外的过滤器。一切都会平稳运行,直到从索引查询得到的文档被收集起来并返回给用户的部分。Solr自定义RequestHandler - 优化结果

基本上,在创建过滤器并执行查询后,我们得到一组文档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); 
    } 
} 

+0

为了说明起见,您创建了此自定义RequestHandler,仅用于向每个请求添加其他过滤器的唯一目的。那是对的吗? – rfeak

+0

@rfeak - 简短的回答,是的。它是相关的吗?你会建议任何不同的方法? – 12N

+1

是的。如果我记得正确(已过去2年),可以在添加到每个查询的XML文件中添加默认过滤器。然后,默认过滤器像其他任何过滤器一样缓存在FilterCache中。它们与其他过滤器的聚合速度应该很快,并且您不必获取文档来应用过滤器。不知道你是否考虑过这种方法。 – rfeak

回答

0

每管理员的要求:

虽然这并没有回答您的具体问题,我建议另一种选择,以解决您的问题。

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

此筛选器与其他任何对象一样对待,所以它被缓存在FilterCache中。结果是在查询时相当快地过滤(通过docIds)。这可以让您避免必须拉取解决方案中的单个文档来应用过滤标准。