I have created a Play 2.1 Scala application. I am uncertain what's the best way to call Solr from a Play application:
- There is no Solr module for Play 2.
- AFAIK all Solr-APIs like SolrJ are blocking.
- I could wrap a SolrJ call into a
Future
, but this will also block a thread, correct? Should I use the
play.api.libs.ws.WS
library to call Solr and use Plays JSON support to extract the result (like in the example below) or is there any easier/faster way?val solrQuery: Future[play.api.libs.ws.Response] = WS.url("http://localhost:8983/solr/collection1/select?q=id%3A123&wt=json").get()
Came across this need recently and didn't find anything useful googling about. Below is only for querying but could be expanded. I'm assuming you want to stay with SolrJ classes. The SolrQuery and QueryResponse are pretty easy to work with.
So to query. You'll want to build up your SolrQuery as normal. For "wt" supply "javabin". This will give you a response in the compressed binary format that SolrJ uses internally.
You'll want to turn your SolrQuery into something that WS understands. (I haven't added all the imports since most are straightforward to figure out [e.g., by your IDE]. Those I have included might not be as obvious.)
In my shop we use a default collection and handler (i.e., "/select") but you'll want those to be overridden by the SolrQuery
You'll need some code to map the WSResponse to a QueryResponse
And that gives you all the pieces to call Solr using Play's async WS service.
Since Play now publishes the webservice code as a standalone jar this means pretty much any project should be able to query Solr asynchronously. Hope that's useful.
Here's how I use WS in my side project:
And here's the utility class I use, the
doParams
is especially useful.You want to wrap the call in a Future with its own Execution context. This way the call may be blocking, but it will use a different thread pool, not blocking the main application.
In fact, this is standard behaviour when facing blocking or slow tasks, like sending queries to a database or doing some heavy-lifting task.