Module: SearchFlip::PostFilterable

Included in:
Criteria
Defined in:
lib/search_flip/post_filterable.rb

Overview

The SearchFlip::PostFilterable mixin provides chainable methods like #post_where, #post_exists, #post_range, etc to add and apply search filters after aggregations have already been calculated.

Examples:

query = ProductIndex.search("harry potter")

query = query.aggregate(price_ranges: {
  range: {
    field: "price",
    ranges: [
      { key: "range1", from: 0,  to: 20 },
      { key: "range2", from: 20, to: 50 },
      { key: "range3", from: 50, to: 100 }
    ]
  }
})

query = query.post_where(price: 20 ... 50)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



24
25
26
27
28
# File 'lib/search_flip/post_filterable.rb', line 24

def self.included(base)
  base.class_eval do
    attr_accessor :post_search_values, :post_must_values, :post_must_not_values, :post_should_values, :post_filter_values
  end
end

Instance Method Details

#post_exists(field) ⇒ SearchFlip::Criteria

Adds a post exists filter to the criteria, which selects all documents for which the specified field has a non-null value.

Examples:

query = CommentIndex.aggregate("...")
query = query.post_exists(:notified_at)

Parameters:

  • field (Symbol, String)

    The field that should have a non-null value

Returns:



232
233
234
# File 'lib/search_flip/post_filterable.rb', line 232

def post_exists(field)
  post_filter exists: { field: field }
end

#post_exists_not(field) ⇒ SearchFlip::Criteria

Adds a post exists not filter to the criteria, which selects all documents for which the specified field’s value is null.

Examples:

query = CommentIndex.aggregate("...")
query = query.post_exists_not(:notified_at)

Parameters:

  • field (Symbol, String)

    The field that should have a null value

Returns:



247
248
249
# File 'lib/search_flip/post_filterable.rb', line 247

def post_exists_not(field)
  post_must_not exists: { field: field }
end

#post_filter(*args) ⇒ SearchFlip::Criteria

Adds raw post filter queries to the criteria.

Examples:

Raw post term filter query

query = CommentIndex.aggregate("...")
query = query.post_filter(term: { state: "new" })

Raw post range filter query

query = CommentIndex.aggregate("...")
query = query.post_filter(range: { created_at: { gte: Time.parse("2016-01-01") }})

Parameters:

  • args (Array, Hash)

    The raw filter query arguments

Returns:



133
134
135
136
137
# File 'lib/search_flip/post_filterable.rb', line 133

def post_filter(*args)
  fresh.tap do |criteria|
    criteria.post_filter_values = (post_filter_values || []) + args
  end
end

#post_must(*args) ⇒ SearchFlip::Criteria

Adds raw post must queries to the criteria.

Examples:

Raw post term must query

query = CommentIndex.aggregate("...")
query = query.post_must(term: { state: "new" })

Raw post range must query

query = CommentIndex.aggregate("...")
query = query.post_must(range: { created_at: { gte: Time.parse("2016-01-01") }})

Parameters:

  • args (Array, Hash)

    The raw must query arguments

Returns:



153
154
155
156
157
# File 'lib/search_flip/post_filterable.rb', line 153

def post_must(*args)
  fresh.tap do |criteria|
    criteria.post_must_values = (post_must_values || []) + args
  end
end

#post_must_not(*args) ⇒ SearchFlip::Criteria

Adds raw post must_not queries to the criteria.

Examples:

Raw post term must_not query

query = CommentIndex.aggregate("...")
query = query.post_must_not(term: { state: "new" })

Raw post range must_not query

query = CommentIndex.aggregate("...")
query = query.post_must_not(range: { created_at: { gte: Time.parse("2016-01-01") }})

Parameters:

  • args (Array, Hash)

    The raw must_not query arguments

Returns:



173
174
175
176
177
# File 'lib/search_flip/post_filterable.rb', line 173

def post_must_not(*args)
  fresh.tap do |criteria|
    criteria.post_must_not_values = (post_must_not_values || []) + args
  end
end

#post_range(field, options = {}) ⇒ SearchFlip::Criteria

Adds a post range filter to the criteria without being forced to specify the left and right end of the range, such that you can eg simply specify lt, lte, gt and gte. For fully specified ranges, you can easily use #post_where, etc. Check out the ElasticSearch docs for further details regarding the range filter.

Examples:

query = CommentIndex.aggregate("...")
query = query.post_range(:created_at, gte: Time.parse("2016-01-01"))

query = CommentIndex.aggregate("...")
query = query.post_range(:likes_count, gt: 10, lt: 100)

Parameters:

  • field (Symbol, String)

    The field name to specify the range for

  • options (Hash) (defaults to: {})

    The range filter specification, like lt, lte, etc

Returns:



217
218
219
# File 'lib/search_flip/post_filterable.rb', line 217

def post_range(field, options = {})
  post_filter range: { field => options }
end

#post_search(q, options = {}) ⇒ SearchFlip::Criteria

Adds a post query string query to the criteria while using AND as the default operator unless otherwise specified. Check out the ElasticSearch docs for further details.

Examples:

CommentIndex.aggregate(:user_id).post_search("message:hello OR message:worl*")

Parameters:

  • q (String)

    The query string query

  • options (Hash) (defaults to: {})

    Additional options for the query string query, like eg default_operator, default_field, etc.

Returns:

Raises:



44
45
46
47
48
49
50
# File 'lib/search_flip/post_filterable.rb', line 44

def post_search(q, options = {})
  raise(SearchFlip::NotSupportedError) if SearchFlip.version.to_i < 2

  fresh.tap do |criteria|
    criteria.post_search_values = (post_search_values || []) + [query_string: { query: q, :default_operator => :AND }.merge(options)] if q.to_s.strip.length > 0
  end
end

#post_should(*args) ⇒ SearchFlip::Criteria

Adds raw post should queries to the criteria.

Examples:

Raw post term should query

query = CommentIndex.aggregate("...")
query = query.post_should(term: { state: "new" })

Raw post range should query

query = CommentIndex.aggregate("...")
query = query.post_should(range: { created_at: { gte: Time.parse("2016-01-01") }})

Parameters:

  • args (Array, Hash)

    The raw should query arguments

Returns:



193
194
195
196
197
# File 'lib/search_flip/post_filterable.rb', line 193

def post_should(*args)
  fresh.tap do |criteria|
    criteria.post_should_values = (post_should_values || []) + args
  end
end

#post_where(hash) ⇒ SearchFlip::Criteria

Adds post filters to your criteria for the supplied hash composed of field-to-filter mappings which specify terms, term or range filters, depending on the type of the respective hash value, namely array, range or scalar type like Fixnum, String, etc.

Examples:

Array values

query = CommentIndex.aggregate("...")
query = query.post_where(id: [1, 2, 3], state: ["approved", "declined"])

Range values

query = CommentIndex.aggregate("...")
query = query.post_where(created_at: Time.parse("2016-01-01") .. Time.parse("2017-01-01"))

Scalar types

query = CommentIndex.aggregate("...")
query = query.post_where(id: 1, message: "hello world")

Parameters:

  • hash (Hash)

    A field-to-filter mapping specifying filter values for the respective fields

Returns:



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/search_flip/post_filterable.rb', line 74

def post_where(hash)
  hash.inject(fresh) do |memo, (key, value)|
    if value.is_a?(Array)
      memo.post_filter terms: { key => value }
    elsif value.is_a?(Range)
      memo.post_filter range: { key => { gte: value.min, lte: value.max } }
    else
      memo.post_filter term: { key => value }
    end
  end
end

#post_where_not(hash) ⇒ SearchFlip::Criteria

Adds post filters to exclude documents in accordance to the supplied hash composed of field-to-filter mappings. Check out #post_where for further details.

Examples:

Array values

query = CommentIndex.aggregate("...")
query = query.post_where_not(id: [1, 2, 3])

Range values

query = CommentIndex.aggregate("...")
query = query.post_where_not(created_at: Time.parse("2016-01-01") .. Time.parse("2017-01-01"))
query = CommentIndex.aggregate("...")
query = query.post_where_not(state: "approved")

Parameters:

  • hash (Hash)

    A field-to-filter mapping specifying filter values for the respective fields

Returns:



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/search_flip/post_filterable.rb', line 107

def post_where_not(hash)
  hash.inject(fresh) do |memo, (key,value)|
    if value.is_a?(Array)
      memo.post_must_not terms: { key => value }
    elsif value.is_a?(Range)
      memo.post_must_not range: { key => { gte: value.min, lte: value.max } }
    else
      memo.post_must_not term: { key => value }
    end
  end
end