PageRenderTime 58ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/scala/scalastic/elasticsearch/Searching.scala

https://github.com/pmanvi/scalastic
Scala | 441 lines | 397 code | 34 blank | 10 comment | 8 complexity | 1cd055456fff28bafdb6f100f504ab4c MD5 | raw file
Possible License(s): Apache-2.0
  1. package scalastic.elasticsearch
  2. import org.elasticsearch.action.search._
  3. import org.elasticsearch.action.support.broadcast._
  4. import org.elasticsearch.index.query._, QueryBuilders._
  5. import org.elasticsearch.search._, facet._, sort._, SortBuilders._, builder._
  6. import scala.collection._, JavaConversions._
  7. import org.elasticsearch.common.geo.{GeoPoint, GeoDistance}
  8. trait Searching
  9. extends Query
  10. with Search
  11. with SearchScroll
  12. with MoreLikeThis
  13. with Multisearch
  14. with Percolate
  15. with ValidateQuery {
  16. self: Indexer =>
  17. }
  18. trait Query {
  19. self: Indexer =>
  20. def query(queryString: String) = query_send(queryString).actionGet
  21. def query_send(queryString: String) = query_prepare(queryString).execute
  22. def query_prepare(queryString: String) = client.prepareSearch().setQuery(queryString)
  23. }
  24. object SearchParameterTypes {
  25. import org.elasticsearch.common.unit._
  26. case class ScriptField(name: String, script: String, parameters: Map[String, Object] = Map(), lang: Option[String] = None)
  27. case class PartialField(name: String, includes: Iterable[String], excludes: Iterable[String]) {
  28. def this(name: String, include: Option[String], exclude: Option[String]) = this(name, include.toIterable, exclude.toIterable)
  29. }
  30. sealed abstract class Sorting(order: SortOrder) {
  31. def newBuilder: SortBuilder
  32. def toBuilder = newBuilder.order(order)
  33. }
  34. case class FieldSort(field: String, ignoreUnmapped: Option[Boolean] = None, missing: Option[Any] = None, order: SortOrder = SortOrder.ASC) extends Sorting(order) {
  35. def newBuilder = {
  36. val builder = fieldSort(field)
  37. ignoreUnmapped.foreach { builder.ignoreUnmapped(_) }
  38. missing.foreach { builder.missing(_) }
  39. builder
  40. }
  41. }
  42. case class ScoreSort(order: SortOrder = SortOrder.ASC) extends Sorting(order) {
  43. def newBuilder = scoreSort
  44. }
  45. case class ScriptSort(script: String, `type`: String, lang: Option[String] = None, parameters: Map[String, Object] = Map(), order: SortOrder = SortOrder.ASC) extends Sorting(order) {
  46. def newBuilder = {
  47. val builder = scriptSort(script, `type`)
  48. lang foreach { builder.lang(_) }
  49. parameters foreach { case (key, value) => builder.param(key, value) }
  50. builder
  51. }
  52. }
  53. case class GeoDistanceSort(field: String, geoDistance: Option[GeoDistance] = None, geohash: Option[String] = None, geoPoint: Option[GeoPoint] = None, unit: Option[DistanceUnit] = None, order: SortOrder = SortOrder.ASC) extends Sorting(order) {
  54. def newBuilder = {
  55. val builder = geoDistanceSort(field)
  56. geoDistance foreach { builder.geoDistance(_) }
  57. geohash foreach { builder.geohash(_) }
  58. geoPoint foreach { each => builder.point(each.lat, each.lon) }
  59. unit foreach { builder.unit(_) }
  60. builder
  61. }
  62. }
  63. case class HighlightField(
  64. name: String,
  65. fragmentSize: Int = -1,
  66. fragmentOffset: Int = -1,
  67. numOfFragments: Int = -1,
  68. requireFieldMatch: Option[Boolean] = None // currently ignored in the Java API
  69. )
  70. case class Highlight(
  71. fields: Iterable[HighlightField] = Nil,
  72. order: Option[String] = None,
  73. requireFieldMatch: Option[Boolean] = None,
  74. encoder: Option[String] = None,
  75. preTags: Iterable[String] = Nil,
  76. postTags: Iterable[String] = Nil,
  77. tagsSchema: Option[String] = None) {
  78. def setIn(request: SearchRequestBuilder) {
  79. fields foreach { f =>
  80. f match {
  81. case HighlightField(name, -1, -1, -1, None) => request.addHighlightedField(name)
  82. case HighlightField(name, fs, -1, -1, None) => request.addHighlightedField(name, fs)
  83. case HighlightField(name, fs, fo, -1, None) => request.addHighlightedField(name, fs, fo)
  84. case HighlightField(name, fs, fo, nf, None) => request.addHighlightedField(name, fs, fo, nf)
  85. case HighlightField(name, fs, fo, nf, Some(r)) => request.addHighlightedField(name, fs, fo, nf)
  86. }
  87. }
  88. order foreach { request.setHighlighterOrder(_) }
  89. requireFieldMatch foreach { request.setHighlighterRequireFieldMatch(_) }
  90. encoder foreach { request.setHighlighterEncoder(_) }
  91. if (!preTags.isEmpty) request.setHighlighterPreTags(preTags.toArray: _*)
  92. if (!postTags.isEmpty) request.setHighlighterPostTags(postTags.toArray: _*)
  93. tagsSchema foreach { request.setHighlighterTagsSchema(_) }
  94. }
  95. }
  96. }
  97. trait SearchScroll {
  98. self: Indexer =>
  99. def searchScroll(
  100. scrollId: String,
  101. listenerThreaded: Option[Boolean] = None,
  102. operationThreading: Option[SearchOperationThreading] = None,
  103. scroll: Option[String] = None) = searchScroll_send(scrollId, listenerThreaded, operationThreading, scroll).actionGet
  104. def searchScroll_send(
  105. scrollId: String,
  106. listenerThreaded: Option[Boolean] = None,
  107. operationThreading: Option[SearchOperationThreading] = None,
  108. scroll: Option[String] = None) = searchScroll_prepare(scrollId, listenerThreaded, operationThreading, scroll).execute
  109. def searchScroll_prepare(
  110. scrollId: String,
  111. listenerThreaded: Option[Boolean] = None,
  112. operationThreading: Option[SearchOperationThreading] = None,
  113. scroll: Option[String] = None) = {
  114. /* method body */
  115. val request = client.prepareSearchScroll(scrollId)
  116. listenerThreaded foreach { request.listenerThreaded(_) }
  117. operationThreading foreach { request.setOperationThreading(_) }
  118. scroll foreach { request.setScroll(_) }
  119. request
  120. }
  121. }
  122. trait Search {
  123. self: Indexer =>
  124. import SearchParameterTypes._
  125. def search(
  126. indices: Iterable[String] = Nil,
  127. types: Iterable[String] = Nil,
  128. query: QueryBuilder = matchAllQuery,
  129. /* the rest ... */
  130. explain: Option[Boolean] = None,
  131. extraSource: Option[Map[String, Object]] = None,
  132. facets: Iterable[FacetBuilder] = Nil,
  133. fields: Iterable[String] = Nil,
  134. filter: Option[FilterBuilder] = None,
  135. from: Option[Int] = None,
  136. highlight: Highlight = Highlight(),
  137. indexBoosts: Map[String, Float] = Map(),
  138. internalBuilder: Option[SearchSourceBuilder] = None,
  139. minScore: Option[Float] = None,
  140. operationThreading: Option[SearchOperationThreading] = None,
  141. partialFields: Iterable[PartialField] = Nil,
  142. preference: Option[String] = None,
  143. queryHint: Option[String] = None,
  144. routing: Option[String] = None,
  145. scriptFields: Iterable[ScriptField] = Nil,
  146. scroll: Option[String] = None,
  147. searchType: Option[SearchType] = None,
  148. size: Option[Int] = None,
  149. sortings: Iterable[Sorting] = Nil,
  150. source: Option[String] = None,
  151. statsGroups: Iterable[String] = Nil,
  152. timeout: Option[String] = None,
  153. trackScores: Option[Boolean] = None) = search_send(indices, types, query, explain, extraSource, facets, fields, filter, from, highlight, indexBoosts, internalBuilder, minScore, operationThreading, partialFields, preference, queryHint, routing, scriptFields, scroll, searchType, size, sortings, source, statsGroups, timeout, trackScores).actionGet
  154. def search_send(
  155. indices: Iterable[String] = Nil,
  156. types: Iterable[String] = Nil,
  157. query: QueryBuilder = matchAllQuery,
  158. /* the rest ... */
  159. explain: Option[Boolean] = None,
  160. extraSource: Option[Map[String, Object]] = None,
  161. facets: Iterable[FacetBuilder] = Nil,
  162. fields: Iterable[String] = Nil,
  163. filter: Option[FilterBuilder] = None,
  164. from: Option[Int] = None,
  165. highlight: Highlight = Highlight(),
  166. indexBoosts: Map[String, Float] = Map(),
  167. internalBuilder: Option[SearchSourceBuilder] = None,
  168. minScore: Option[Float] = None,
  169. operationThreading: Option[SearchOperationThreading] = None,
  170. partialFields: Iterable[PartialField] = Nil,
  171. preference: Option[String] = None,
  172. queryHint: Option[String] = None,
  173. routing: Option[String] = None,
  174. scriptFields: Iterable[ScriptField] = Nil,
  175. scroll: Option[String] = None,
  176. searchType: Option[SearchType] = None,
  177. size: Option[Int] = None,
  178. sortings: Iterable[Sorting] = Nil,
  179. source: Option[String] = None,
  180. statsGroups: Iterable[String] = Nil,
  181. timeout: Option[String] = None,
  182. trackScores: Option[Boolean] = None) = search_prepare(indices, types, query, explain, extraSource, facets, fields, filter, from, highlight, indexBoosts, internalBuilder, minScore, operationThreading, partialFields, preference, routing, scriptFields, scroll, searchType, size, sortings, source, statsGroups, timeout, trackScores).execute
  183. def search_prepare(
  184. indices: Iterable[String] = Nil,
  185. types: Iterable[String] = Nil,
  186. query: QueryBuilder = matchAllQuery,
  187. /* the rest ... */
  188. explain: Option[Boolean] = None,
  189. extraSource: Option[Map[String, Object]] = None,
  190. facets: Iterable[FacetBuilder] = Nil,
  191. fields: Iterable[String] = Nil,
  192. filter: Option[FilterBuilder] = None,
  193. from: Option[Int] = None,
  194. highlight: Highlight = Highlight(),
  195. indexBoosts: Map[String, Float] = Map(),
  196. internalBuilder: Option[SearchSourceBuilder] = None,
  197. minScore: Option[Float] = None,
  198. operationThreading: Option[SearchOperationThreading] = None,
  199. partialFields: Iterable[PartialField] = Nil,
  200. preference: Option[String] = None,
  201. routing: Option[String] = None,
  202. scriptFields: Iterable[ScriptField] = Nil,
  203. scroll: Option[String] = None,
  204. searchType: Option[SearchType] = None,
  205. size: Option[Int] = None,
  206. sortings: Iterable[Sorting] = Nil,
  207. source: Option[String] = None,
  208. statsGroups: Iterable[String] = Nil,
  209. timeout: Option[String] = None,
  210. trackScores: Option[Boolean] = None) = {
  211. /* method body */
  212. // ... essentials
  213. val request = client.prepareSearch(indices.toArray: _*)
  214. request.setTypes(types.toArray: _*)
  215. request.setQuery(query)
  216. // ... and the rest
  217. explain foreach { request.setExplain(_) }
  218. extraSource foreach { request.setExtraSource(_) }
  219. facets foreach { request.addFacet(_) }
  220. fields foreach { request.addField(_) }
  221. filter foreach { request.setFilter(_) }
  222. from foreach { request.setFrom(_) }
  223. highlight.setIn(request)
  224. indexBoosts foreach { case (key, value) => request.addIndexBoost(key, value) }
  225. internalBuilder foreach { request.internalBuilder(_) }
  226. minScore foreach { request.setMinScore(_) }
  227. operationThreading foreach { request.setOperationThreading(_) }
  228. partialFields foreach { each => request.addPartialField(each.name, each.includes.toArray, each.excludes.toArray) }
  229. preference foreach { request.setPreference(_) }
  230. routing foreach { request.setRouting(_) }
  231. scriptFields foreach { each => request.addScriptField(each.name, each.lang getOrElse (null), each.script, each.parameters) }
  232. scroll foreach { request.setScroll(_) }
  233. searchType foreach { request.setSearchType(_) }
  234. size foreach { request.setSize(_) }
  235. sortings foreach { each => request.addSort(each.toBuilder) }
  236. source foreach { request.setSource(_) }
  237. if (!statsGroups.isEmpty) request.setStats(statsGroups.toArray: _*)
  238. timeout foreach { request.setTimeout(_) }
  239. trackScores foreach { request.setTrackScores(_) }
  240. request
  241. }
  242. }
  243. trait Multisearch {
  244. self: Indexer =>
  245. def multisearch(requests: Iterable[SearchRequestBuilder] = Seq(search_prepare())) = multisearch_send(requests = requests).actionGet
  246. def multisearch_send(requests: Iterable[SearchRequestBuilder] = Seq(search_prepare())) = multisearch_prepare(requests = requests).execute
  247. def multisearch_prepare(requests: Iterable[SearchRequestBuilder] = Seq(search_prepare())) = {
  248. val request = client.prepareMultiSearch
  249. for (each <- requests) request.add(each)
  250. request
  251. }
  252. def multisearchByQuery(queries: Iterable[QueryBuilder] = Seq(matchAllQuery)) = multisearchByQuery_send(queries = queries).actionGet
  253. def multisearchByQuery_send(queries: Iterable[QueryBuilder] = Seq(matchAllQuery)) = multisearchByQuery_prepare(queries = queries).execute
  254. def multisearchByQuery_prepare(queries: Iterable[QueryBuilder] = Seq(matchAllQuery)) = multisearch_prepare(queries map (each => search_prepare(query = each)))
  255. }
  256. trait MoreLikeThis {
  257. self: Indexer =>
  258. def moreLikeThis(
  259. index: String,
  260. `type`: String,
  261. id: String,
  262. boostTerms: Option[Float] = None,
  263. fields: Iterable[String] = Nil,
  264. maxDocFreq: Option[Int] = None,
  265. maxQueryTerms: Option[Int] = None,
  266. maxWordLen: Option[Int] = None,
  267. minDocFreq: Option[Int] = None,
  268. minTermFreq: Option[Int] = None,
  269. minWordLen: Option[Int] = None,
  270. percentTermsToMatch: Option[Float] = None,
  271. from: Option[Int] = None,
  272. searchIndices: Iterable[String] = Nil,
  273. searchScroll: Option[Scroll] = None,
  274. searchSize: Option[Int] = None,
  275. searchSource: Option[Map[String, Object]] = None,
  276. searchType: Option[SearchType] = None,
  277. searchTypes: Iterable[String] = Nil,
  278. stopwords: Iterable[String] = Nil) = moreLikeThis_send(index, `type`, id, boostTerms, fields, maxDocFreq, maxQueryTerms, maxWordLen, minDocFreq, minTermFreq, minWordLen, percentTermsToMatch, from, searchIndices, searchScroll, searchSize, searchSource, searchType, searchTypes, stopwords).actionGet
  279. def moreLikeThis_send(
  280. index: String,
  281. `type`: String,
  282. id: String,
  283. boostTerms: Option[Float] = None,
  284. fields: Iterable[String] = Nil,
  285. maxDocFreq: Option[Int] = None,
  286. maxQueryTerms: Option[Int] = None,
  287. maxWordLen: Option[Int] = None,
  288. minDocFreq: Option[Int] = None,
  289. minTermFreq: Option[Int] = None,
  290. minWordLen: Option[Int] = None,
  291. percentTermsToMatch: Option[Float] = None,
  292. from: Option[Int] = None,
  293. searchIndices: Iterable[String] = Nil,
  294. searchScroll: Option[Scroll] = None,
  295. searchSize: Option[Int] = None,
  296. searchSource: Option[Map[String, Object]] = None,
  297. searchType: Option[SearchType] = None,
  298. searchTypes: Iterable[String] = Nil,
  299. stopwords: Iterable[String] = Nil) = moreLikeThis_prepare(index, `type`, id, boostTerms, fields, maxDocFreq, maxQueryTerms, maxWordLen, minDocFreq, minTermFreq, minWordLen, percentTermsToMatch, from, searchIndices, searchScroll, searchSize, searchSource, searchType, searchTypes, stopwords).execute
  300. def moreLikeThis_prepare(
  301. index: String,
  302. `type`: String,
  303. id: String,
  304. boostTerms: Option[Float] = None,
  305. fields: Iterable[String] = Nil,
  306. maxDocFreq: Option[Int] = None,
  307. maxQueryTerms: Option[Int] = None,
  308. maxWordLen: Option[Int] = None,
  309. minDocFreq: Option[Int] = None,
  310. minTermFreq: Option[Int] = None,
  311. minWordLen: Option[Int] = None,
  312. percentTermsToMatch: Option[Float] = None,
  313. from: Option[Int] = None,
  314. searchIndices: Iterable[String] = Nil,
  315. searchScroll: Option[Scroll] = None,
  316. searchSize: Option[Int] = None,
  317. searchSource: Option[Map[String, Object]] = None,
  318. searchType: Option[SearchType] = None,
  319. searchTypes: Iterable[String] = Nil,
  320. stopwords: Iterable[String] = Nil) = {
  321. /* method body */
  322. val request = client.prepareMoreLikeThis(index, `type`, id)
  323. boostTerms foreach { request.setBoostTerms(_) }
  324. if (!fields.isEmpty) request.setField(fields.toArray: _*)
  325. maxDocFreq foreach { request.setMaxDocFreq(_) }
  326. maxQueryTerms foreach { request.maxQueryTerms(_) }
  327. maxWordLen foreach { request.setMaxWordLen(_) }
  328. minDocFreq foreach { request.setMinDocFreq(_) }
  329. minTermFreq foreach { request.setMinTermFreq(_) }
  330. minWordLen foreach { request.setMinWordLen(_) }
  331. percentTermsToMatch foreach { request.setPercentTermsToMatch(_) }
  332. from foreach { request.setSearchFrom(_) }
  333. if (!searchIndices.isEmpty) request.setSearchIndices(searchIndices.toArray: _*)
  334. searchScroll foreach { request.setSearchScroll(_) }
  335. searchSize foreach { request.setSearchSize(_) }
  336. searchSource foreach { request.setSearchSource(_) }
  337. searchType foreach { request.setSearchType(_) }
  338. if (!searchTypes.isEmpty) request.setSearchTypes(searchTypes.toArray: _*)
  339. if (!stopwords.isEmpty) request.setStopWords(stopwords.toArray: _*)
  340. request
  341. }
  342. }
  343. trait Percolate {
  344. self: Indexer =>
  345. def percolate(
  346. index: String,
  347. `type`: String,
  348. listenerThreaded: Option[Boolean] = None,
  349. operationThreaded: Option[Boolean] = None,
  350. preferLocal: Option[Boolean] = None,
  351. source: Option[String] = None) = percolate_send(index, `type`, listenerThreaded, operationThreaded, preferLocal, source).actionGet
  352. def percolate_send(
  353. index: String,
  354. `type`: String,
  355. listenerThreaded: Option[Boolean] = None,
  356. operationThreaded: Option[Boolean] = None,
  357. preferLocal: Option[Boolean] = None,
  358. source: Option[String] = None) = percolate_prepare(index, `type`, listenerThreaded, operationThreaded, preferLocal, source).execute
  359. def percolate_prepare(
  360. index: String,
  361. `type`: String,
  362. listenerThreaded: Option[Boolean] = None,
  363. operationThreaded: Option[Boolean] = None,
  364. preferLocal: Option[Boolean] = None,
  365. source: Option[String] = None) = {
  366. /* method body */
  367. val request = client.preparePercolate(index, `type`)
  368. listenerThreaded foreach { request.setListenerThreaded(_) }
  369. operationThreaded foreach { request.setOperationThreaded(_) }
  370. preferLocal foreach { request.setPreferLocal(_) }
  371. source foreach { request.setSource(_) }
  372. request
  373. }
  374. }
  375. trait ValidateQuery {
  376. self: Indexer =>
  377. def validateQuery(
  378. indices: Iterable[String] = Nil,
  379. types: Iterable[String] = Nil,
  380. query: QueryBuilder = matchAllQuery,
  381. explain: Option[Boolean] = None,
  382. listenerThreaded: Option[Boolean] = None,
  383. operationThreading: Option[BroadcastOperationThreading] = None) = validateQuery_send(indices, types, query, explain, listenerThreaded, operationThreading).actionGet
  384. def validateQuery_send(
  385. indices: Iterable[String] = Nil,
  386. types: Iterable[String] = Nil,
  387. query: QueryBuilder = matchAllQuery,
  388. explain: Option[Boolean] = None,
  389. listenerThreaded: Option[Boolean] = None,
  390. operationThreading: Option[BroadcastOperationThreading] = None) = validateQuery_prepare(indices, types, query, explain, listenerThreaded, operationThreading).execute
  391. def validateQuery_prepare(
  392. indices: Iterable[String] = Nil,
  393. types: Iterable[String] = Nil,
  394. query: QueryBuilder = matchAllQuery,
  395. explain: Option[Boolean] = None,
  396. listenerThreaded: Option[Boolean] = None,
  397. operationThreading: Option[BroadcastOperationThreading] = None) = {
  398. /* method body */
  399. val request = client.admin.indices.prepareValidateQuery(indices.toArray: _*)
  400. request.setTypes(types.toArray: _*)
  401. request.setQuery(query)
  402. explain foreach { request.setExplain(_) }
  403. listenerThreaded foreach { request.setListenerThreaded(_) }
  404. operationThreading foreach { request.setOperationThreading(_) }
  405. request
  406. }
  407. }