class Elastic
Constants
- COUNT
- HITS
- HOST
- ID
- INDEX
- SCORE
- TOTAL
Public Class Methods
client()
click to toggle source
# File lib/co-elastic-query.rb, line 307 def self.client @@client end
count(*args)
click to toggle source
# File lib/co-elastic-query.rb, line 303 def self.count *args @@client.count *args end
new(klass = nil, **opts)
click to toggle source
# File lib/co-elastic-query.rb, line 322 def initialize(klass = nil, **opts) if klass @klass = klass @filter = klass.design_document end @index = opts[:index] || INDEX @use_couch_type = opts[:use_couch_type] || false end
new_client()
click to toggle source
# File lib/co-elastic-query.rb, line 311 def self.new_client @@client = Elasticsearch::Client.new hosts: HOST, reload_connections: true, adapter: :libuv end
search(*args)
click to toggle source
# File lib/co-elastic-query.rb, line 299 def self.search *args @@client.search *args end
Public Instance Methods
count(builder)
click to toggle source
# File lib/co-elastic-query.rb, line 368 def count(builder) query = generate_body(builder) # Simplify the query query[:body].delete(:from) query[:body].delete(:size) query[:body].delete(:sort) Elastic.count(query)[COUNT] end
generate_body(builder)
click to toggle source
# File lib/co-elastic-query.rb, line 380 def generate_body(builder) opt = builder.build sort = (opt[:sort] || []) + SCORE queries = opt[:queries] || [] queries.unshift(opt[:query]) filters = opt[:filters] || [] if @filter if @use_couch_type filters.unshift({term: {'doc.type' => @filter}}) else filters.unshift({type: {value: @filter}}) end end { index: @index, body: { sort: sort, query: { bool: { must: { query: { bool: { must: queries } } }, filter: { bool: { must: filters } } } }, from: opt[:offset], size: opt[:limit] } } end
query(params = nil, filters = nil)
click to toggle source
Safely build the query
# File lib/co-elastic-query.rb, line 332 def query(params = nil, filters = nil) builder = ::Elastic::Query.new(params) builder.filter(filters) if filters builder end
search(builder) { |record| ... }
click to toggle source
# File lib/co-elastic-query.rb, line 338 def search(builder, &block) query = generate_body(builder) # if a formatter block is supplied, each loaded record is passed to it # allowing annotation/conversion of records using data from the model # and current request (e.g groups are annotated with 'admin' if the # currently logged in user is an admin of the group). nils are removed # from the list. result = Elastic.search(query) records = if @klass Array(@klass.find_by_id(result[HITS][HITS].map {|entry| entry[ID]})) else Array(result[HITS][HITS].map { |entry| ::CouchbaseOrm.try_load(entry[ID]) }).compact end results = block_given? ? (records.map {|record| yield record}).compact : records # Ensure the total is accurate total = result[HITS][TOTAL] || 0 total = total - (records.length - results.length) # adjust for compaction # We check records against limit (pre-compaction) and total against actual result length # Worst case senario is there is one additional request for results at an offset that returns no results. # The total results number will be accurate on the final page of results from the clients perspective. total = results.length + builder.offset if records.length < builder.limit && total > (results.length + builder.offset) { total: total, results: results } end