module Elasticsearch module Model # Contains functionality related to searching. # module Searching # Wraps a search request definition # class SearchRequest attr_reader :klass, :definition, :options # @param klass [Class] The class of the model # @param query_or_payload [String,Hash,Object] The search request definition # (string, JSON, Hash, or object responding to `to_hash`) # @param options [Hash] Optional parameters to be passed to the Elasticsearch client # def initialize(klass, query_or_payload, options={}) @klass = klass @options = options __index_name = options[:index] || klass.index_name __document_type = options[:type] || klass.document_type case # search query: ... when query_or_payload.respond_to?(:to_hash) body = query_or_payload.to_hash # search '{ "query" : ... }' when query_or_payload.is_a?(String) && query_or_payload =~ /^\s*{/ body = query_or_payload # search '...' else q = query_or_payload end if body @definition = { index: __index_name, type: __document_type, body: body }.update options else @definition = { index: __index_name, type: __document_type, q: q }.update options end end # Performs the request and returns the response from client # # @return [Hash] The response from Elasticsearch # def execute! klass.client.search(@definition) end end module ClassMethods # Provides a `search` method for the model to easily search within an index/type # corresponding to the model settings. # # @param query_or_payload [String,Hash,Object] The search request definition # (string, JSON, Hash, or object responding to `to_hash`) # @param options [Hash] Optional parameters to be passed to the Elasticsearch client # # @return [Elasticsearch::Model::Response::Response] # # @example Simple search in `Article` # # Article.search 'foo' # # @example Search using a search definition as a Hash # # response = Article.search \ # query: { # match: { # title: 'foo' # } # }, # highlight: { # fields: { # title: {} # } # }, # size: 50 # # response.results.first.title # # => "Foo" # # response.results.first.highlight.title # # => ["Foo"] # # response.records.first.title # # Article Load (0.2ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" IN (1, 3) # # => "Foo" # # @example Search using a search definition as a JSON string # # Article.search '{"query" : { "match_all" : {} }}' # def search(query_or_payload, options={}) search = SearchRequest.new(self, query_or_payload, options) Response::Response.new(self, search) end end end end end