最近遇到了这种需求,并没有发现任何有用的谷歌搜索。以下仅用于查询,但可以扩展。我假设您想继续使用 SolrJ 课程。SolrQuery 和 QueryResponse 非常容易使用。
所以去查询。您需要像往常一样构建 SolrQuery。对于“wt”,提供“javabin”。这将以 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()
}
}
// p1: SolrJ pulls the same cast
// p2: We didn't use a SolrServer to chat with Solr so cannot provide it to QueryResponse
new QueryResponse(jbcUnmarshal.asInstanceOf[NamedList[Object]], null)
}
这为您提供了使用 Play 的异步 WS 服务调用 Solr 的所有部分。
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)
}
由于 Play 现在将 web 服务代码作为独立的 jar 发布,这意味着几乎任何项目都应该能够异步查询 Solr。希望这很有用。