Class: Redis::Commands::Search::Query
- Inherits:
-
Object
- Object
- Redis::Commands::Search::Query
- Defined in:
- lib/redis/commands/modules/search/query.rb
Overview
A fluent builder for FT.SEARCH query strings and their options.
Chainable setter methods (+filter+, paging, sort_by, ...) return self so calls can
be strung together, and a predicate DSL (+tag+/+text+/+numeric+ combined with +and_+/+or_+)
builds the query string itself. #to_redis_args renders the whole thing into the argument
array passed to FT.SEARCH.
Instance Attribute Summary collapse
- #filters ⇒ Hash, ... readonly
- #geo_filters ⇒ Hash, ... readonly
- #highlight_options ⇒ Array, ...
- #options ⇒ Hash, ... readonly
- #return_fields ⇒ Array, ...
- #return_fields_decode ⇒ Hash, ... readonly
- #summarize_options ⇒ Array, ...
Class Method Summary collapse
-
.build { ... } ⇒ Query
Build a Query by evaluating
blockin the context of a fresh instance.
Instance Method Summary collapse
-
#add_predicate(predicate) ⇒ self
Add a built predicate to the current collection.
-
#and_ { ... } ⇒ self
Open an AND group: predicates added inside
blockare joined with a space. -
#dialect(dialect_version) ⇒ self
Set the query
DIALECTversion. -
#evaluate { ... } ⇒ Object?
Evaluate
blockagainst this query (used to populate it via the DSL). -
#expander(expander_name) ⇒ self
Set the query
EXPANDER(custom query expander). -
#expander_value ⇒ Object
:nodoc:.
-
#explain_score ⇒ self
Return an explanation of the score of each document (+EXPLAINSCORE+).
-
#filter(field, min, max = nil) ⇒ self
Add a numeric
FILTERclause. -
#geo_filter(field, lon, lat, radius, unit = 'km') ⇒ self
Add a
GEOFILTERclause restricting results to a radius around a point. -
#highlight(fields: nil, tags: ["<b>", "</b>"]) ⇒ self
Configure result +HIGHLIGHT+ing.
-
#in_order ⇒ self
Require query terms to appear in the same order as in the query (+INORDER+).
-
#in_order_value ⇒ Object
:nodoc:.
-
#initialize(base = nil) ⇒ Query
constructor
A new instance of Query.
-
#language(lang) ⇒ self
Set the query
LANGUAGEused for stemming. -
#language_value ⇒ Object
:nodoc:.
-
#limit_fields(*fields) ⇒ self
Restrict the search to the given fields (+INFIELDS+).
-
#limit_fields_value ⇒ Object
:nodoc:.
-
#limit_ids(*ids) ⇒ self
Restrict the search to the given document ids (+INKEYS+).
-
#limit_ids_value ⇒ Object
Internal getters used by Index#search to read accumulated state - unlike the chainable setters above, these return the stored value rather than
self. -
#new_collection(type) { ... } ⇒ self
Push a new predicate collection of
type, evaluate the block against it, then fold it back into the parent collection. -
#no_content ⇒ self
Return only document ids, without their contents (+NOCONTENT+).
-
#no_content_value ⇒ Object
:nodoc:.
-
#no_stopwords ⇒ self
Do not filter out stopwords (+NOSTOPWORDS+).
-
#no_stopwords_value ⇒ Object
:nodoc:.
-
#numeric(field) ⇒ NumericField
Begin a numeric-field predicate bound to this query (call +.gt+/+.lt+/+.between+ on it).
-
#or_ { ... } ⇒ self
Open an OR group: predicates added inside
blockare joined with|. -
#paging(offset, limit) ⇒ self
Set the
LIMIT(paging) for the result set. -
#return(*fields) ⇒ self
Set the fields to
RETURN, replacing any previously configured ones. -
#return_field(field, as_field: nil, decode_field: true) ⇒ self
Append a single field to
RETURN, optionally aliased and/or JSON-decoded. -
#scorer(scorer_name) ⇒ self
Set the scoring function (+SCORER+).
-
#slop(value) ⇒ self
Set the allowed
SLOP(number of intervening terms) for phrase matching. -
#slop_value ⇒ Object
:nodoc:.
-
#sort_by(field, order = nil, asc: true) ⇒ self
Set the
SORTBYfield and direction. -
#summarize(fields: nil, separator: "...", len: 20, frags: 3) ⇒ self
Configure result +SUMMARIZE+ation (fragment extraction around matches).
-
#tag(field) ⇒ TagField
Begin a tag-field predicate bound to this query (call
.eqon the result). -
#text(field) ⇒ TextField
Begin a text-field predicate bound to this query (call
.matchon the result). -
#timeout(milliseconds) ⇒ self
Set the query
TIMEOUT. -
#timeout_value ⇒ Object
:nodoc:.
-
#to_redis_args ⇒ Array
Render the query and all configured options into the
FT.SEARCHargument array. -
#verbatim ⇒ self
Disable stemming for the query (+VERBATIM+).
-
#verbatim_value ⇒ Object
:nodoc:.
-
#with_payloads ⇒ self
Return the payload attached to each document (+WITHPAYLOADS+).
-
#with_payloads_value ⇒ Object
:nodoc:.
-
#with_scores ⇒ self
Return the relevance score of each document (+WITHSCORES+).
Constructor Details
#initialize(base = nil) ⇒ Query
Returns a new instance of Query.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/redis/commands/modules/search/query.rb', line 30 def initialize(base = nil) @base = base @predicate_collection = [PredicateCollection.new(:and)] @filters = [] @options = { dialect: DEFAULT_DIALECT } # Default dialect, matching redis-py @return_fields = [] @return_fields_decode = {} @summarize_options = nil @highlight_options = nil @language = nil @verbatim = false @no_stopwords = false @with_payloads = false @slop = nil @in_order = false @no_content = false @limit_ids = nil end |
Instance Attribute Details
#filters ⇒ Hash, ... (readonly)
23 24 25 |
# File 'lib/redis/commands/modules/search/query.rb', line 23 def filters @filters end |
#geo_filters ⇒ Hash, ... (readonly)
23 24 25 |
# File 'lib/redis/commands/modules/search/query.rb', line 23 def geo_filters @geo_filters end |
#highlight_options ⇒ Array, ...
27 28 29 |
# File 'lib/redis/commands/modules/search/query.rb', line 27 def @highlight_options end |
#options ⇒ Hash, ... (readonly)
23 24 25 |
# File 'lib/redis/commands/modules/search/query.rb', line 23 def @options end |
#return_fields ⇒ Array, ...
27 28 29 |
# File 'lib/redis/commands/modules/search/query.rb', line 27 def return_fields @return_fields end |
#return_fields_decode ⇒ Hash, ... (readonly)
23 24 25 |
# File 'lib/redis/commands/modules/search/query.rb', line 23 def return_fields_decode @return_fields_decode end |
#summarize_options ⇒ Array, ...
27 28 29 |
# File 'lib/redis/commands/modules/search/query.rb', line 27 def @summarize_options end |
Class Method Details
.build { ... } ⇒ Query
Build a Query by evaluating block in the context of a fresh instance.
56 57 58 59 60 |
# File 'lib/redis/commands/modules/search/query.rb', line 56 def self.build(&block) instance = new instance.instance_eval(&block) instance end |
Instance Method Details
#add_predicate(predicate) ⇒ self
Add a built predicate to the current collection.
398 399 400 401 |
# File 'lib/redis/commands/modules/search/query.rb', line 398 def add_predicate(predicate) @predicate_collection.last.add(predicate) self end |
#and_ { ... } ⇒ self
Open an AND group: predicates added inside block are joined with a space.
390 391 392 |
# File 'lib/redis/commands/modules/search/query.rb', line 390 def and_(&block) new_collection(:and, &block) end |
#dialect(dialect_version) ⇒ self
Set the query DIALECT version.
304 305 306 307 |
# File 'lib/redis/commands/modules/search/query.rb', line 304 def dialect(dialect_version) @options[:dialect] = dialect_version self end |
#evaluate { ... } ⇒ Object?
Evaluate block against this query (used to populate it via the DSL).
473 474 475 476 477 |
# File 'lib/redis/commands/modules/search/query.rb', line 473 def evaluate(&block) if block_given? instance_eval(&block) end end |
#expander(expander_name) ⇒ self
Set the query EXPANDER (custom query expander).
189 190 191 192 |
# File 'lib/redis/commands/modules/search/query.rb', line 189 def () @expander = self end |
#expander_value ⇒ Object
:nodoc:
370 371 372 |
# File 'lib/redis/commands/modules/search/query.rb', line 370 def @expander end |
#explain_score ⇒ self
Return an explanation of the score of each document (+EXPLAINSCORE+).
312 313 314 315 |
# File 'lib/redis/commands/modules/search/query.rb', line 312 def explain_score @options[:explainscore] = true self end |
#filter(field, min, max = nil) ⇒ self
Add a numeric FILTER clause.
Bounds are validated so a malformed or untrusted value can't inject query syntax, the
same guarantee the numeric-predicate DSL gives. Beyond plain numbers, the RediSearch
bound forms +inf+/+-inf+ and the exclusive ( prefix (e.g. "(10") are accepted.
73 74 75 76 77 |
# File 'lib/redis/commands/modules/search/query.rb', line 73 def filter(field, min, max = nil) max ||= min @filters << [field, coerce_filter_bound(min), coerce_filter_bound(max)] self end |
#geo_filter(field, lon, lat, radius, unit = 'km') ⇒ self
Add a GEOFILTER clause restricting results to a radius around a point.
87 88 89 90 91 |
# File 'lib/redis/commands/modules/search/query.rb', line 87 def geo_filter(field, lon, lat, radius, unit = 'km') @geo_filters ||= [] @geo_filters << [field, lon, lat, radius, unit] self end |
#highlight(fields: nil, tags: ["<b>", "</b>"]) ⇒ self
Configure result +HIGHLIGHT+ing.
275 276 277 278 279 280 281 |
# File 'lib/redis/commands/modules/search/query.rb', line 275 def highlight(fields: nil, tags: ["<b>", "</b>"]) @highlight_options = { fields: Array(fields), tags: } self end |
#in_order ⇒ self
Require query terms to appear in the same order as in the query (+INORDER+).
239 240 241 242 |
# File 'lib/redis/commands/modules/search/query.rb', line 239 def in_order @in_order = true self end |
#in_order_value ⇒ Object
:nodoc:
355 356 357 |
# File 'lib/redis/commands/modules/search/query.rb', line 355 def in_order_value @in_order end |
#language(lang) ⇒ self
Set the query LANGUAGE used for stemming.
172 173 174 175 |
# File 'lib/redis/commands/modules/search/query.rb', line 172 def language(lang) @language = lang self end |
#language_value ⇒ Object
:nodoc:
325 326 327 |
# File 'lib/redis/commands/modules/search/query.rb', line 325 def language_value @language end |
#limit_fields(*fields) ⇒ self
Restrict the search to the given fields (+INFIELDS+).
265 266 267 268 |
# File 'lib/redis/commands/modules/search/query.rb', line 265 def limit_fields(*fields) @limit_fields = fields self end |
#limit_fields_value ⇒ Object
:nodoc:
365 366 367 |
# File 'lib/redis/commands/modules/search/query.rb', line 365 def limit_fields_value @limit_fields end |
#limit_ids(*ids) ⇒ self
Restrict the search to the given document ids (+INKEYS+).
97 98 99 100 |
# File 'lib/redis/commands/modules/search/query.rb', line 97 def limit_ids(*ids) @limit_ids = ids self end |
#limit_ids_value ⇒ Object
Internal getters used by Index#search to read accumulated state - unlike the
chainable setters above, these return the stored value rather than self.
:nodoc:
320 321 322 |
# File 'lib/redis/commands/modules/search/query.rb', line 320 def limit_ids_value @limit_ids end |
#new_collection(type) { ... } ⇒ self
Push a new predicate collection of type, evaluate the block against it, then fold it
back into the parent collection.
409 410 411 412 413 414 415 416 |
# File 'lib/redis/commands/modules/search/query.rb', line 409 def new_collection(type) collection = PredicateCollection.new(type) @predicate_collection << collection yield if block_given? @predicate_collection.pop @predicate_collection.last.add(collection) self end |
#no_content ⇒ self
Return only document ids, without their contents (+NOCONTENT+).
256 257 258 259 |
# File 'lib/redis/commands/modules/search/query.rb', line 256 def no_content @no_content = true self end |
#no_content_value ⇒ Object
:nodoc:
340 341 342 |
# File 'lib/redis/commands/modules/search/query.rb', line 340 def no_content_value @no_content end |
#no_stopwords ⇒ self
Do not filter out stopwords (+NOSTOPWORDS+).
197 198 199 200 |
# File 'lib/redis/commands/modules/search/query.rb', line 197 def no_stopwords @no_stopwords = true self end |
#no_stopwords_value ⇒ Object
:nodoc:
335 336 337 |
# File 'lib/redis/commands/modules/search/query.rb', line 335 def no_stopwords_value @no_stopwords end |
#numeric(field) ⇒ NumericField
Begin a numeric-field predicate bound to this query (call +.gt+/+.lt+/+.between+ on it).
438 439 440 |
# File 'lib/redis/commands/modules/search/query.rb', line 438 def numeric(field) NumericField.new(field, self) end |
#or_ { ... } ⇒ self
Open an OR group: predicates added inside block are joined with |.
382 383 384 |
# File 'lib/redis/commands/modules/search/query.rb', line 382 def or_(&block) new_collection(:or, &block) end |
#paging(offset, limit) ⇒ self
Set the LIMIT (paging) for the result set.
107 108 109 110 |
# File 'lib/redis/commands/modules/search/query.rb', line 107 def paging(offset, limit) @options[:limit] = [offset, limit] self end |
#return(*fields) ⇒ self
Set the fields to RETURN, replacing any previously configured ones.
138 139 140 141 142 143 144 |
# File 'lib/redis/commands/modules/search/query.rb', line 138 def return(*fields) @return_fields = fields # Replacing the RETURN list drops any decode flags set via #return_field; otherwise a # stale flag would keep decoding an overlapping field name in the new list. @return_fields_decode = {} self end |
#return_field(field, as_field: nil, decode_field: true) ⇒ self
Append a single field to RETURN, optionally aliased and/or JSON-decoded.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/redis/commands/modules/search/query.rb', line 152 def return_field(field, as_field: nil, decode_field: true) @return_fields ||= [] @return_fields_decode ||= {} @return_fields << field # Results are keyed by the alias when one is given (Redis returns the value under AS), # so the decode flag must be keyed the same way or hashify_fields won't match it. @return_fields_decode[as_field || field] = decode_field if as_field @return_fields << "AS" << as_field end self end |
#scorer(scorer_name) ⇒ self
Set the scoring function (+SCORER+).
214 215 216 217 |
# File 'lib/redis/commands/modules/search/query.rb', line 214 def scorer(scorer_name) @options[:scorer] = scorer_name self end |
#slop(value) ⇒ self
Set the allowed SLOP (number of intervening terms) for phrase matching.
231 232 233 234 |
# File 'lib/redis/commands/modules/search/query.rb', line 231 def slop(value) @slop = value self end |
#slop_value ⇒ Object
:nodoc:
350 351 352 |
# File 'lib/redis/commands/modules/search/query.rb', line 350 def slop_value @slop end |
#sort_by(field, order = nil, asc: true) ⇒ self
Set the SORTBY field and direction.
Supports both styles: a positional order ("ASC"/"DESC" symbol or string) and the
asc: keyword. When order is given it takes precedence over asc:.
121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/redis/commands/modules/search/query.rb', line 121 def sort_by(field, order = nil, asc: true) # Support both old style (order as symbol/string) and new style (asc as boolean) direction = if order.nil? # New style: use asc parameter asc ? "ASC" : "DESC" else # Old style: order is a symbol or string order.to_s.upcase end @options[:sortby] = [field, direction] self end |
#summarize(fields: nil, separator: "...", len: 20, frags: 3) ⇒ self
Configure result +SUMMARIZE+ation (fragment extraction around matches).
290 291 292 293 294 295 296 297 298 |
# File 'lib/redis/commands/modules/search/query.rb', line 290 def summarize(fields: nil, separator: "...", len: 20, frags: 3) @summarize_options = { fields: Array(fields), separator: separator, len: len, frags: frags } self end |
#tag(field) ⇒ TagField
Begin a tag-field predicate bound to this query (call .eq on the result).
422 423 424 |
# File 'lib/redis/commands/modules/search/query.rb', line 422 def tag(field) TagField.new(field, self) end |
#text(field) ⇒ TextField
Begin a text-field predicate bound to this query (call .match on the result).
430 431 432 |
# File 'lib/redis/commands/modules/search/query.rb', line 430 def text(field) TextField.new(field, self) end |
#timeout(milliseconds) ⇒ self
Set the query TIMEOUT.
248 249 250 251 |
# File 'lib/redis/commands/modules/search/query.rb', line 248 def timeout(milliseconds) @timeout = milliseconds self end |
#timeout_value ⇒ Object
:nodoc:
360 361 362 |
# File 'lib/redis/commands/modules/search/query.rb', line 360 def timeout_value @timeout end |
#to_redis_args ⇒ Array
Render the query and all configured options into the FT.SEARCH argument array.
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 |
# File 'lib/redis/commands/modules/search/query.rb', line 446 def to_redis_args args = [query_string] (args) append_scorer(args) append_with_scores(args) append_limit_fields(args) append_limit_ids(args) append_filters(args) append_geo_filters(args) append_return_fields(args) (args) (args) append_slop(args) append_timeout(args) append_language(args) (args) append_in_order(args) append_sort_by(args) append_limit(args) append_dialect(args) args.flatten end |
#verbatim ⇒ self
Disable stemming for the query (+VERBATIM+).
180 181 182 183 |
# File 'lib/redis/commands/modules/search/query.rb', line 180 def verbatim @verbatim = true self end |
#verbatim_value ⇒ Object
:nodoc:
330 331 332 |
# File 'lib/redis/commands/modules/search/query.rb', line 330 def verbatim_value @verbatim end |
#with_payloads ⇒ self
Return the payload attached to each document (+WITHPAYLOADS+).
222 223 224 225 |
# File 'lib/redis/commands/modules/search/query.rb', line 222 def with_payloads @with_payloads = true self end |
#with_payloads_value ⇒ Object
:nodoc:
345 346 347 |
# File 'lib/redis/commands/modules/search/query.rb', line 345 def with_payloads_value @with_payloads end |
#with_scores ⇒ self
Return the relevance score of each document (+WITHSCORES+).
205 206 207 208 |
# File 'lib/redis/commands/modules/search/query.rb', line 205 def with_scores @options[:withscores] = true self end |