Search Smith

ColdFusion, SQL queries, and, of course, searching

ColdFusion and Solr: Dealing with the results

Posted by David Faber on March 8, 2012

The Solr web service allows you to return results in either XML format or JSON (the format is XML by default; to return results in JSON format, add the parameter “wt=json” to your Solr query string). Suppose we run a query on the Solr collection myindex. There are three ways we can search this collection: (1) we could use the <cfsearch> tag; (2) we could use the Solr web service and return XML; or (3) we could use the Solr web service and return JSON. We’ve talked about <cfsearch> and its limitations before so I’ll limit this discussion to the second and third options.


<cfhttp url="http://localhost:8983/solr/myindex?q=*:*&fl=*,score" result="myresult" />


<cfhttp url="http://localhost:8983/solr/myindex?q=*:*&fl=*,score&wt=json" result="myresult" />

In each case (XML or JSON), ColdFusion has powerful functions that help you manage the data without needing to parse it manually. Typically I create a friendly query that I can return to the front-end developer that he can use in place of a SQL query or <cfsearch> result.

<cfset search_results = queryNew("id,title,description,pubdate,journal_name,author_name,num_reads,score"
<!--- We're using our articles index mentioned in a previous post --->


<cfif isXML(myresult)>
    <cfset xml_result = XMLParse(myresult.fileContent) />
    <!--- continue processing --->


<cfif isJSON(myresult)>
    <cfset json_result = deserializeJSON(myresult.fileContent) />
    <!--- continue processing --->

In either case we will iterate over our results structure and put the results in our friendly query.

The JSON structure is particularly friendly for our purposes. First, let’s get the number of results and the maximum score:

<cfset result_cnt = json_result.response.numFound />
<cfset max_score = json_result.response.maxScore />

These fields aren’t absolutely necessary, of course. In particular, maxScore seems superfluous but it might be useful if you’re converting from Verity to Solr and need scores in a % format. The Verity search engine scores results between 0 and 1, which is easily converted to a percentage; while Solr has no maximum score. So to get a Verity-style score, simply divide each result’s score by maxScore.

Now we simply loop over the docs array of the response:

<cfloop array="" index="doc">
    <cfif structKeyExists(doc, "id") AND structKeyExists(doc, "title")>
        <!--- Both id and title are absolutely required --->
        <cfset queryAddRow(search_results) />
        <cfset querySetCell(search_results, "id", doc[id]) />
        <cfset querySetCell(search_results, "title", doc[title]) />
        <cfset querySetCell(search_results, "score", doc[score] / max_score) />
        <cfif structKeyExists(doc, "description")>
            <cfset querySetCell(search_results, "description", doc[description]) />
        <cfif structKeyExists(doc, "pub_date")>
            <cfset querySetCell(search_results, "pub_date", doc[pub_date]) />
        <cfif structKeyExists(doc, "journal_name")>
            <cfset querySetCell(search_results, "journal_name", doc[journal_name]) />
        <cfif structKeyExists(doc, "author_name")>
            <cfset querySetCell(search_results, "author_name", doc[author_name]) />
        <cfif structKeyExists(doc, "read_cnt")>
            <cfset querySetCell(search_results, "read_cnt", doc[read_cnt]) />

Dealing with XML results is a bit more complicated so I will discuss that in a subsequent post or in an update to this one. Suffice it to say that the approach will be very similar – we will iterate over the results and store them in a friendly query.

7 Responses to “ColdFusion and Solr: Dealing with the results”

  1. […] ColdFusion and Solr: Dealing with the results […]

  2. Ryan said

    What if there were multiple (an array of) authors?

  3. David Faber said

    I guess there are a number of ways you might handle it. When the JSON is deserialized CF will turn the array of authors into a ColdFusion array. You could then turn the array into a list in order to store it in a query column. Or you might turn the array back into a JSON object! In any case, I don’t think that querySetCell() works when the value is complex (array, struct, query, etc.).

    FYI, Having multiple authors will prevent you from being able to sort on the authors field in Solr, unless you have a separate field for the primary author.

  4. Ryan said

    Thank you – I thought of the ArraytoList option after I made my previous comment. That works fine for what I need. Your tutorial was very helpful.

  5. George Murphy said

    Have you ever tried using an xlst document to parse the returning xml to produce nice readable html?
    George Murphy

  6. David Faber said

    Correct me if I’m wrong, but wouldn’t that simply display the results in some friendly format? There wouldn’t be an option, say, to save the results for future reference.

  7. George Murphy said

    You are correct, that would give you more control over how your results were displayed.

Leave a Comment

Your email address will not be published. Required fields are marked *