. , . , SolrJ. SolrQuery QueryResponse .
, . SolrQuery . "wt" "". , SolrJ .
val sq = new SolrQuery()
sq.set("wt", "javabin")
...
SolrQuery -, WS. ( , (, IDE). , , .)
import scala.collection.JavaConverters._
def solrQueryToForm(sq: SolrQuery): Map[String, Seq[String]] = {
sq.getParameterNames.asScala.foldLeft(Map.empty[String, Seq[String]]) {
case (m, n) =>
m + (n -> sq.getParams(n))
}
}
(.. "/select" ), , SolrQuery
def solrEndpoint(sq: SolrQuery): String = {
val coll = sq.get("collection", defaultCollection)
val hand = Option(sq.getRequestHandler).getOrElse(defaultHandler)
formSolrEndpoint(solrUrl, coll, hand)
}
def formSolrEndpoint(base: String, collection: String, handler: String): String = {
val sb = new StringBuilder(base)
if (sb.last != '/') sb.append('/')
sb.append(collection)
if (!handler.startsWith("/")) sb.append('/')
sb.append(handler)
sb.result()
}
WSResponse QueryResponse
import com.ning.http.client.{Response => ACHResponse}
def wsResponseToQueryResponse(wsResponse: WSResponse)(implicit ctx: ExecutionContext): QueryResponse = {
val jbcUnmarshal = {
val rbis = wsResponse.underlying[ACHResponse].getResponseBodyAsStream
try {
new JavaBinCodec().unmarshal(rbis)
}
finally {
if (rbis != null)
rbis.close()
}
}
new QueryResponse(jbcUnmarshal.asInstanceOf[NamedList[Object]], null)
}
Solr, async WS.
def query(sq: SolrQuery)(implicit ctx: ExecutionContext): Future[QueryResponse] = {
val sqstar = sq.getCopy
sqstar.set("wt", "javabin")
WS.url(solrEndpoint(sqstar))
.post(solrQueryToForm(sqstar))
.map(wsResponseToQueryResponse)
}
Since Play now publishes the webservice code as a separate jar, this means that almost any project should be able to request Solr asynchronously. Hope this is helpful.