debian-mirror-gitlab/elasticsearch-model/lib/elasticsearch/model/searching.rb
2019-12-22 22:52:31 +05:30

109 lines
3.5 KiB
Ruby

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
# # => ["<em>Foo</em>"]
#
# 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