Skip to content

Commit

Permalink
Merge pull request #104 from theablefew/refactor/query_method_specs
Browse files Browse the repository at this point in the history
Add better specs for query methods and query builder
  • Loading branch information
esmarkowski authored Mar 26, 2024
2 parents d6bd219 + 89317c0 commit f12b6a5
Show file tree
Hide file tree
Showing 30 changed files with 1,328 additions and 275 deletions.
5 changes: 4 additions & 1 deletion lib/stretchy/attributes/transformers/keyword_transformer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ def protected?(arg)
# this is for text fields that have a keyword subfield
# `:text` and `:string` fields add a `:keyword` subfield to the attribute mapping automatically
def transform(item, *ignore)
return unless Stretchy.configuration.auto_target_keywords
return item unless Stretchy.configuration.auto_target_keywords
if item.is_a?(String)
return (!protected?(item) && keyword_available?(item)) ? "#{item}.#{keyword_field_for(item)}" : item
end
item.each_with_object({}) do |(key, value), new_item|
if ignore && ignore.include?(key)
new_item[key] = value
Expand Down
60 changes: 30 additions & 30 deletions lib/stretchy/relations/query_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def regexes
end

def fields
values[:field]
values[:fields]
end

def source
Expand Down Expand Up @@ -150,24 +150,21 @@ def build_query

structure.hybrid do
structure.queries do
hybrid[:neural].each do |n|
structure.child! do
params = n.dup
field_name, query_text = params.shift
structure.neural do
structure.set! field_name do
structure.query_text query_text
structure.extract! params, *params.keys
end
end
structure.child! do
params = hybrid[:neural].dup
field_name, query_text = params.shift
structure.neural do
structure.set! field_name do
structure.query_text query_text
structure.extract! params, *params.keys
end
end
end

hybrid[:query].each do |query|
structure.child! do
structure.extract! query, *query.keys
end
end
structure.child! do
hybrid_query = hybrid[:query].dup
structure.extract! hybrid_query, *hybrid_query.keys
end

end
end unless hybrid.nil?
Expand Down Expand Up @@ -222,7 +219,7 @@ def build_query

def build_regexp
regexes.each do |args|
target_field = args.first.keys.first
target_field = keyword_transformer.transform(args.first.keys.first.to_s)
value_field = args.first.values.first
structure.set! target_field, args.last.merge(value: value_field)
end
Expand Down Expand Up @@ -300,7 +297,7 @@ def build_search_options

def extra_search_options
unless self.count?
values[:size] = size.present? ? size : values[:default_size]
values[:size] = size.present? ? size : default_size
else
values[:size] = nil
end
Expand All @@ -310,7 +307,7 @@ def extra_search_options
def compact_where(q, opts = {bool:true})
return if q.nil?
if opts.delete(:bool)
as_must(q)
as_must([merge_and_append(q)])
else
as_query_string(q.flatten)
end
Expand Down Expand Up @@ -343,26 +340,29 @@ def as_query_string(q)

q.each do |arg|
arg.each_pair { |k,v| _and << "(#{k}:#{v})" } if arg.class == Hash
_and << "(#{arg})" if arg.class == String
if q.length == 1
_and << "#{arg}" if arg.class == String
else
_and << "(#{arg})" if arg.class == String
end
end
_and.join(" AND ")
end

def merge_and_append(queries)
builder = {}

queries.each do |q|
q.each do |k, v|
if builder.key?(k)
builder[k] = builder[k].class == Array ? builder[k] : [builder[k]]
builder[k] << v
result = {}
queries.each do |hash|
hash.each do |key, value|
if result[key].is_a?(Array)
result[key] << value
elsif result.key?(key)
result[key] = [result[key], value]
else
builder[k] = v
result[key] = value
end
end
end

builder
result
end

def extract_highlighter(highlighter)
Expand Down
2 changes: 1 addition & 1 deletion lib/stretchy/relations/query_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def registry
MULTI_VALUE_METHODS = [
:where,
:order,
:field,
:fields,
:highlight,
:source,
:must_not,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Stretchy
module Relations
module QueryMethods
module Field
module Fields
extend ActiveSupport::Concern

# Specify the fields to be returned by the Elasticsearch query.
Expand Down Expand Up @@ -49,16 +49,16 @@ module Field
# Model.fields('books.*')
# ```
#
def field(*args)
def fields(*args)
spawn.field!(*args)
end

# Alias for {#field}
# @see #field
alias :fields :field
alias :field :fields

def field!(*args) # :nodoc:
self.field_values += args
self.fields_values += args
self
end

Expand Down
2 changes: 1 addition & 1 deletion lib/stretchy/relations/query_methods/hybrid.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def hybrid(opts)
end

def hybrid!(opts) # :nodoc:
self.hybrid_values += [opts]
self.hybrid_values = opts
self
end

Expand Down
16 changes: 3 additions & 13 deletions lib/stretchy/relations/query_methods/query_string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,12 @@ module QueryString
# ```
#
def query_string(opts = :chain, *rest)
if opts == :chain
WhereChain.new(spawn)
elsif opts.blank?
self
else
spawn.query_string!(opts, *rest)
end
spawn.query_string!(opts, *rest)
end

def query_string!(opts, *rest) # :nodoc:
if opts == :chain
WhereChain.new(self)
else
self.query_string_values += build_where(opts, rest)
self
end
self.query_string_values += build_where(opts, rest)
self
end

QueryMethods.register!(:query_string)
Expand Down
2 changes: 0 additions & 2 deletions lib/stretchy/relations/query_methods/regexp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ def regexp!(args) # :nodoc:
args = args.to_a
target_field, regex = args.shift
opts = args.to_h
opts.reverse_merge!(use_keyword: true)
target_field = "#{target_field}.keyword" if opts.delete(:use_keyword)
opts.merge!(case_insensitive: true) if regex.casefold?
self.regexp_values += [[Hash[target_field, regex.source], opts]]
self
Expand Down
7 changes: 5 additions & 2 deletions lib/stretchy/relations/query_methods/where.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,11 @@ def where(opts = :chain, *rest)
opts.each do |key, value|
case value
when Range
opts.delete(key)
between(value, key)
range = opts.delete(key)
range_options = {gte: range.begin}
upper_bound = range.exclude_end? ? :lt : :lte
range_options[upper_bound] = range.end
filter_query(:range, key => range_options)
when Hash
opts.delete(key)
filter_query(:range, key => value) if value.keys.any? { |k| [:gte, :lte, :gt, :lt].include?(k) }
Expand Down
1 change: 1 addition & 0 deletions spec/models/test_model.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class TestModel < StretchyModel
attribute :name, :text
attribute :title, :keyword
attribute :age, :integer
attribute :tags, :array
attribute :data, :hash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class MyModel < Stretchy::Record

it 'does not transform' do
transformed_keywords = values[:where].map do |arg|
described_class.new(model.attribute_types).transform(arg)
expect(described_class.new(model.attribute_types).transform(arg)).to eq(arg)
end
end
end
Expand Down
9 changes: 0 additions & 9 deletions spec/stretchy/neural_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,6 @@
expect(described_class).to respond_to(:neural)
end

it 'adds values' do
values = described_class.neural(passage_embedding: { query_text: 'hello world', model_id: '1234'}).values[:neural]
expect(values.first).to eq({passage_embedding: { query_text: 'hello world', model_id: '1234'}})
end

it 'returns results' do
allow_any_instance_of(Elasticsearch::Persistence::Repository).to receive(:search).and_return(results)
expect(described_class.neural(passage_embedding: 'hello world', model_id: '1234', k:2).total).to eq(2)
Expand All @@ -152,10 +147,6 @@
expect(described_class).to respond_to(:hybrid)
end

it 'adds values' do
values = described_class.hybrid(neural: [{passage_embedding: 'hello world', model_id: '1234', k: 2}], query: [{term: {status: :active}}]).values[:hybrid]
expect(values).to eq([{neural: [{passage_embedding: 'hello world', model_id: '1234', k: 2}], query: [{term: {status: :active}}]}])
end
end


Expand Down
Loading

0 comments on commit f12b6a5

Please sign in to comment.