Class: Tantiny::Query
- Inherits:
-
Object
- Object
- Tantiny::Query
- Defined in:
- lib/tantiny/query.rb
Constant Summary collapse
- TYPES =
%i[ all empty term fuzzy_term phrase regex range facet smart prefix ].freeze
- DEFAULT_BOOST =
1.0- DEFAULT_FUZZY_DISTANCE =
1
Class Method Summary collapse
- .all_query(_index = nil) ⇒ Object
- .conjunction(*queries) ⇒ Object
- .disjunction(*queries) ⇒ Object
- .empty_query(_index = nil) ⇒ Object
- .facet_query(index, field, path, **options) ⇒ Object
- .fuzzy_term_query(index, fields, term, distance = DEFAULT_FUZZY_DISTANCE, **options) ⇒ Object
- .phrase_query(index, fields, phrase, **options) ⇒ Object
- .prefix_query(index, fields, prefix, **options) ⇒ Object
- .range_query(index, fields, range, **options) ⇒ Object
- .regex_query(index, fields, regex, **options) ⇒ Object
- .smart_query(index, fields, query_string, **options) ⇒ Object
- .term_query(index, fields, term, **options) ⇒ Object
Instance Method Summary collapse
Class Method Details
.all_query(_index = nil) ⇒ Object
27 28 29 |
# File 'lib/tantiny/query.rb', line 27 def all_query(_index = nil) __new_all_query end |
.conjunction(*queries) ⇒ Object
17 18 19 20 |
# File 'lib/tantiny/query.rb', line 17 def conjunction(*queries) # @type var queries: Array[untyped] queries.one? ? queries.first : __conjunction(queries) end |
.disjunction(*queries) ⇒ Object
22 23 24 25 |
# File 'lib/tantiny/query.rb', line 22 def disjunction(*queries) # @type var queries: Array[untyped] queries.one? ? queries.first : __disjunction(queries) end |
.empty_query(_index = nil) ⇒ Object
31 32 33 |
# File 'lib/tantiny/query.rb', line 31 def empty_query(_index = nil) __new_empty_query end |
.facet_query(index, field, path, **options) ⇒ Object
87 88 89 90 |
# File 'lib/tantiny/query.rb', line 87 def facet_query(index, field, path, **) allowed_fields = index.schema.facet_fields construct_query(index, :facet, allowed_fields, field, [path], **) end |
.fuzzy_term_query(index, fields, term, distance = DEFAULT_FUZZY_DISTANCE, **options) ⇒ Object
40 41 42 43 44 |
# File 'lib/tantiny/query.rb', line 40 def fuzzy_term_query(index, fields, term, distance = DEFAULT_FUZZY_DISTANCE, **) params = [term.to_s, distance.to_i] allowed_fields = text_and_strings(index) construct_query(index, :fuzzy_term, allowed_fields, fields, params, **) end |
.phrase_query(index, fields, phrase, **options) ⇒ Object
46 47 48 49 50 51 52 53 54 |
# File 'lib/tantiny/query.rb', line 46 def phrase_query(index, fields, phrase, **) queries = [*fields].map do |f| terms = index.schema.tokenizer_for(f).terms(phrase) allowed_fields = index.schema.text_fields construct_query(index, :phrase, allowed_fields, f, [terms], **) end queries.empty? ? empty_query : disjunction(*queries) end |
.prefix_query(index, fields, prefix, **options) ⇒ Object
61 62 63 |
# File 'lib/tantiny/query.rb', line 61 def prefix_query(index, fields, prefix, **) regex_query(index, fields, Regexp.escape(prefix) + ".*", **) end |
.range_query(index, fields, range, **options) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/tantiny/query.rb', line 65 def range_query(index, fields, range, **) schema = index.schema case range.first when Integer allowed_fields = schema.integer_fields from, to = [range.min, range.max] when Float allowed_fields = schema.double_fields from, to = [range.first, range.last] when Date, DateTime # @type var range: Range[Date | DateTime] allowed_fields = schema.date_fields from, to = [Helpers.(range.first), Helpers.(range.last)] else raise UnsupportedRange.new(range.first.class) end # @type var allowed_fields: Array[Symbol] construct_query(index, :range, allowed_fields, fields, [from, to], **) end |
.regex_query(index, fields, regex, **options) ⇒ Object
56 57 58 59 |
# File 'lib/tantiny/query.rb', line 56 def regex_query(index, fields, regex, **) allowed_fields = text_and_strings(index) construct_query(index, :regex, allowed_fields, fields, [regex.to_s], **) end |
.smart_query(index, fields, query_string, **options) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/tantiny/query.rb', line 92 def smart_query(index, fields, query_string, **) fuzzy_distance = [:fuzzy_distance] boost_factor = .fetch(:boost, DEFAULT_BOOST) field_queries = [*fields].map do |field| terms = index.schema.tokenizer_for(field).terms(query_string) # See: https://github.com/soutaro/steep/issues/272 # @type block: nil | Query next if terms.empty? term_queries = terms.map do |term| if fuzzy_distance.nil? term_query(index, field, term) else fuzzy_term_query(index, field, term, fuzzy_distance) end end # @type var terms: untyped # @type var term_queries: untyped last_term_query = prefix_query(index, field, terms.last) | term_queries.last conjunction(last_term_query, *term_queries[0...-1]) end.compact disjunction(*field_queries).boost(boost_factor) end |
.term_query(index, fields, term, **options) ⇒ Object
35 36 37 38 |
# File 'lib/tantiny/query.rb', line 35 def term_query(index, fields, term, **) allowed_fields = text_and_strings(index) construct_query(index, :term, allowed_fields, fields, [term.to_s], **) end |
Instance Method Details
#! ⇒ Object
155 156 157 |
# File 'lib/tantiny/query.rb', line 155 def ! __negation end |
#&(other) ⇒ Object
149 150 151 152 153 |
# File 'lib/tantiny/query.rb', line 149 def &(other) raise ArgumentError.new("Not a #{self.class}.") unless other.is_a?(self.class) self.class.conjunction(self, other) end |
#boost(boost_factor) ⇒ Object
159 160 161 162 163 |
# File 'lib/tantiny/query.rb', line 159 def boost(boost_factor) return self if boost_factor == DEFAULT_BOOST __boost(boost_factor.to_f) end |
#|(other) ⇒ Object
143 144 145 146 147 |
# File 'lib/tantiny/query.rb', line 143 def |(other) raise ArgumentError.new("Not a #{self.class}.") unless other.is_a?(self.class) self.class.disjunction(self, other) end |