Using Solrj it is possible to read Documents from a QueryResponse
as (annotated) beans:
List<Item> items = queryResponse.getBeans(Item.class)
Where Item is the annotated class that maps to a Solr Document.
Now I query for a single document and ask for 10 MoreLikeThis documents:
?q=id:AZ133007&mlt=true&mlt.fl=technique,subject&mlt.mindf=1&mlt.mintf=1&mlt.count=10
This returns the document with id AZ133007
together with 10 'MoreLikeThis' documents (i.e. more like AZ133007
with regard to fields 'technique' and 'subject'). See the (simplified) response below:
<response>
<lst name="responseHeader">
...
</lst>
<result name="response" numFound="1" start="0">
<doc>
<str name="id">AZ133007</str>
<str name="title">Still I</str>
<str name="artist">A.R. Tist</str>
<str name="technique">Watercolor</str>
<str name="subject">Still life</str>
</doc>
</result>
<lst name="moreLikeThis">
<result name="AZ133007" numFound="84" start="0">
<doc>
<str name="id">AZ002001</str>
<str name="title">Cubes</str>
<str name="artist">John Doe</str>
<str name="technique">Watercolor</str>
<str name="subject">Landscape</str>
</doc>
<doc>
<str name="id">AZ002002</str>
<str name="title">Cats and Dogs</str>
<str name="artist">A. Nothername</str>
<str name="technique">Watercolor</str>
<str name="subject">Cityscape</str>
</doc>
...
</result>
</lst>
</response>
The requested document AZ133007
in the response
section can be returned as an Item
bean like so:
Item item = queryResponse.getBeans(Item.class).get(0);
But how do I get the documents listed under 'moreLikeThis' as beans?
After a lot of experimenting, browsing the web and digging into the Solrj API I came with the following solution. There may be better ways to do it, I would really like to know.
First extract the moreLikeThis
section from the response and cast it to a NamedList
:
NamedList mlt = (NamedList) queryResponse.getResponse().get("moreLikeThis");
Inspecting the NamedList
mlt
while debugging, it shows the AZ133007
entry along with the SolrDocuments that are 'moreLikeThis'.
{
AZ133007={
numFound=295,
start=0,
docs=[
SolrDocument{
id=AZ002001,
title=Cubes,
artist=JohnDoe,
technique=Watercolor,
subject=Landscape
},
SolrDocument{
id=AZ002002,
title=CatsAndDogs,
artist=A.Nothername,
technique=Watercolor,
subject=Cityscape
},
...
]
}
}
Now get a SolrDocumentList
providing the id:
SolrDocumentList mltDocList = (SolrDocumentList) mlt.get("AZ133007");
And bind this SolrDocumentList
to beans:
DocumentObjectBinder b = new DocumentObjectBinder();
List<Item> similarItems = b.getBeans(Item.class, mltDocList);
Of course I didn't hard-code the id and I'd built in some null checks, but you get the idea.