Scala и полнотекстовый поиск с Amazon CloudSearch
17 августа 2015
CloudSearch является сервисом полнотекстового поиска в облаке Amazon’а. То есть, что-то вроде ElasticSearch или Solr, который не обязательно понимать, главное любить и кормить вовремя не нужно настраивать и поддерживать, главное вовремя оплачивать. В этой заметке будет показан простой пример использования Amazon CloudSearch на языке Scala.
Настройка Amazon CloudSearch через веб-интерфейс до безобразия проста, поэтому не будем на ней даже останавливаться, тем более, что веб-интерфейсы все равно часто меняются.
А вот, собственно, и код:
import com.amazonaws.services.cloudsearchdomain._
import com.amazonaws.services.cloudsearchdomain.model._
import org.json4s._
import org.json4s.jackson.JsonMethods._
import java.io._
import java.nio.charset._
import scala.collection.JavaConverters._
object CloudSearchExample extends App {
val cloudsearchEndpoint = "https://abcefg.cloudsearch.amazonaws.com"
val accessKey = "ACCESSKEY123"
val secretKey = "SECRETKEY456"
val credentials = new BasicAWSCredentials(accessKey, secretKey)
val client = new AmazonCloudSearchDomainClient(credentials)
client.setEndpoint(cloudsearchEndpoint)
val docType = "message"
val docTypeLen = docType.length
// -------- upload --------
{
val j = compact(render(JArray(List(
JObject(List(
"type" -> JString("add"),
"id" -> JString(s"${docType}23456"),
"fields" -> JObject(List(
"text" -> JString("test test"),
"type" -> JString(docType)
))
))
))))
val bytes = j.getBytes(StandardCharsets.UTF_8)
val stream = new ByteArrayInputStream(bytes)
val req = new UploadDocumentsRequest()
req.setContentType("application/json")
req.setContentLength(bytes.length.toLong)
req.setDocuments(stream)
val res = client.uploadDocuments(req)
println(res.toString)
}
// -------- search --------
{
val req = new SearchRequest
req.setQuery(s"""text:"test test" AND type:"${docType}" """)
req.setQueryParser(QueryParser.Lucene)
val res = client.search(req)
val hits = res.getHits.getHit.asScala
val ids = hits.map(_.getId).filter(_.startsWith(docType))
.map(_.drop(docTypeLen).toLong)
println(s"Ids: $ids")
}
}
Как видите, приходится построить немного JSON-а вручную, воспользовавшись уже знакомым нам json4s. Обратите внимание, что в строке:
… слово AND
обязательно должно быть в верхнем регистре, иначе запрос просто тихо не найдет ни одного документа.
В остальном, как мне кажется, пример предельно прост и не нуждается в особых пояснениях. Шлется запрос на добавление:
… документа с определенным id и полями, затем посылается запрос на поиск документа по полям. Возвращается список наиболее релевантных документов, из него выдираются id найденных документов и показываются пользователю. В реальном приложении вам, понятное дело, придется завести пул с нитками ОС и обернуть все хождения в CloudSearch в футуры, так как вряд ли вы хотите просто брать и делать блокирующие вызовы в своем бэкенде.
А работаете ли вы с CloudSearch или иной системой полнотекстового поиска?
Дополнение: Также вас может заинтересовать пост Основы полнотекстового поиска в PostgreSQL.
Метки: Scala, Облака, Функциональное программирование.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.