aboutsummaryrefslogtreecommitdiff
blob: 39742dacf8a0b2b3ad446c65fecc552d265086f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
require 'forwardable'
require 'singleton'

class BaseRepository
  include Elasticsearch::Persistence::Repository
  include Elasticsearch::Persistence::Repository::DSL
  include Singleton

  client ElasticsearchClient.default

  class << self
    extend Forwardable
    def_delegators :instance, :find_all_by, :filter_all, :find_by, :find_all_by_parent, :all_sorted_by
    def_delegators :instance, :find_sorted_by, :n_sorted_by
    def_delegators :instance, :count, :search, :delete, :save, :refresh_index!, :create_index
  end

  # Finds instances by exact IDs using the 'term' filter
  def find_all_by(field, value, opts = {})
    search({
      size: 10_000,
      query: { match: { field => value } }
    }.merge(opts))
  end

  # Filter all instances by the given parameters
  def filter_all(filters, opts = {})
    filter_args = []
    filters.each_pair { |field, value| filter_args << { term: { field => value } } }

    search({
      query: {
        bool: { filter: { bool: { must: filter_args } } }
      },
      size: 10_000
    }.merge(opts))
  end

  def find_by(field, value, opts = {})
    find_all_by(field, value, opts).first
  end

  def find_all_by_parent(parent, opts = {})
    search(opts.merge(
             size: 10_000,
             query: {
               bool: {
                 filter: {
                   has_parent: {
                     parent_type: parent.class.document_type,
                     query: { term: { _id: parent.id } }
                   }
                 },
                 must: {
                   match_all: {}
                 }
               }
             }
           ))
  end

  # Returns the given number of records of this class sorted by a field.
  def find_sorted_by(field, value, sort_field, order, num_return, options = {})
    search({
      size: num_return,
      query: { term: { field => value } },
      sort: { sort_field => { order: order } }
    }.merge(options))
  end

  # Returns n records of this class sorted by a field.
  def n_sorted_by(n, field, order, options = {})
    search({
      size: n,
      query: { match_all: {} },
      sort: { field => { order: order } }
    }.merge(options))
  end

  # Returns all (by default 10k) records of this class sorted by a field.
  def all_sorted_by(field, order, options = {})
    search({
      size: 10_000,
      query: { match_all: {} },
      sort: { field => { order: order } }
    }.merge(options))
  end

  # Converts the model to an OpenStruct instance
  #
  # @param [Array<Symbol>] fields Fields to export into the OpenStruct, or all fields if nil
  # @return [OpenStruct] OpenStruct containing the selected fields
  def to_os(*fields)
    fields = all_fields if fields.empty?
    OpenStruct.new(Hash[fields.map { |field| [field, send(field)] }])
  end

  # Converts the model to a Hash
  #
  # @param [Array<Symbol>] fields Fields to export into the Hash, or all fields if nil
  # @return [Hash] Hash containing the selected fields
  def to_hsh(*fields)
    fields = all_fields if fields.empty?
    Hash[fields.map { |field| [field, send(field)] }]
  end
end