views:

26

answers:

2

I'm searching an Solr index with SolrJ and trying to get the Lucene explanation for logging it for further use.

The code goes like this:

    SolrServer server = new CommonsHttpSolrServer("solr_url");
    SolrQuery solrquery = new SolrQuery();
    solrquery.set("fl", "score, id"); // id is a String field
    solrquery.set("rows", "1000");
    solrquery.set("debugQuery", "on");
    solrquery.setQuery("query words here");

    try {
        QueryResponse response = server.query(solrquery);
        SolrDocumentList docs = response.getResults();
        Iterator<SolrDocument> dociterator = docs.iterator();

        while (dociterator.hasNext())
        {
            SolrDocument doc = dociterator.next();
            String id = (String) doc.getFirstValue(idfield);
            Float relevance = (Float) doc.getFirstValue("score");
            String explanation = ???;
        }
    } catch (SolrServerException e) {
        e.printStackTrace();
    }

I figured that response.getEplainMap() would contain a map with the value like response.getEplainMap().get(id) , but it seems that the explainmap contains only the key null with the value of the last found document.

Any ideas how to get the correct explanation?

+1  A: 

Have you tried debugging a query from the admin console? This shows you the full output.

QueryResponse has a couple of methods getDebugMap() and getExplainMap() that might prove useful. I haven't tested it in code but on the admin console when I debug a query I get the following;

<?xml version="1.0" encoding="UTF-8"?>
<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">0</int>
    <lst name="params">
      <str name="q">stuff</str>
      <str name="start">0</str>
      <str name="indent">on</str>
      <str name="explainOther"/>
      <str name="wt">standard</str>
      <str name="hl.fl"/>
      <str name="fq"/>
      <str name="version">2.2</str>
      <str name="qt">standard</str>
      <str name="debugQuery">on</str>
      <str name="fl">*,score</str>
      <str name="rows">1</str>
    </lst>
  </lst>
  <result name="response" numFound="79" start="0" maxScore="4.050907">
    <doc>
      <float name="score">4.050907</float>
      ..other bits of data
     </doc>
  </result>
  <lst name="debug">
    <str name="rawquerystring">stuff</str>
    <str name="querystring">stuff</str>
    <str name="parsedquery">MYSEARCHFIELD:stuff</str>
    <str name="parsedquery_toString">MYSEARCHFIELD:stuff</str>
    <lst name="explain">
      <str name="6095">     <--- 6095 is the ID of the document
        4.050907 = (MATCH) fieldWeight(MYSEARCHFIELD:stuff in 1292), product of:
        1.4142135 = tf(termFreq(MYSEARCHFIELD:stuff )=2)
        9.166156 = idf(docFreq=79, maxDocs=281583)
        0.3125 = fieldNorm(field=MYSEARCHFIELD, doc=1292)
      </str>
    </lst>

    ..timing stuff here

  </lst>
</response>
Qwerky
As mentioned in my own answer the ids were wrong (read: non-existent). However, if I had read your answer before I figured out the problem by myself I would've seen my it from the debug query console since I believe the explain output didn't have the name/id -attribute at all like in your post. So in a way by posting that you solved my problem too :)
Timo
A: 

In my case there was a bug in the Solr index itself. Code below works now.

Map<String, String> explainmap = response.getExplainMap();
String explanation = explainmap.get(id);

When creating an index and having problems like above make sure that the id field determined in schema.xml (e.g. <uniqueKey>id</uniqueKey>) contains correct data. In my case the id field I used in the code was not the same as Solr thought it was and it contained no data, thus the explainmap had only one field with a key null.

Timo