Class: Queries::TaxonName::Autocomplete

Inherits:
Query
  • Object
show all
Defined in:
lib/queries/taxon_name/autocomplete.rb

Instance Attribute Summary collapse

Attributes inherited from Query

#dynamic_limit, #options, #project_id, #query_string, #terms

Instance Method Summary collapse

Methods inherited from Query

#alphabetic_strings, #autocomplete_cached, #autocomplete_cached_wildcard_anywhere, #autocomplete_exact_id, #autocomplete_exactly_named, #autocomplete_named, #autocomplete_ordered_wildcard_pieces_in_cached, #build_terms, #cached, #combine_or_clauses, #end_wildcard, #exactly_named, #fragments, #integers, #match_ordered_wildcard_pieces_in_cached, #match_wildcard_end_in_cached, #match_wildcard_in_cached, #named, #no_terms?, #only_ids, #only_integers?, #parent, #parent_child_join, #parent_child_where, #pieces, #result, #scope, #start_and_end_wildcard, #start_wildcard, #wildcard_pieces, #wildcard_wrapped_integers, #wildcard_wrapped_years, #with_cached, #with_cached_like, #with_id, #with_project_id, #year_letter, #years

Constructor Details

#initialize(string, project_id: nil, valid: nil, exact: nil, no_leaves: nil, nomenclature_group: [], type: [], parent_id: []) ⇒ Autocomplete

Returns a new instance of Autocomplete

Parameters:

  • args (Hash)


37
38
39
40
41
42
43
44
45
# File 'lib/queries/taxon_name/autocomplete.rb', line 37

def initialize(string, project_id: nil, valid: nil, exact: nil, no_leaves: nil, nomenclature_group: [], type: [], parent_id: [])
  @nomenclature_group = nomenclature_group
  @valid = valid == 'true' ? true : (valid == 'false' ? false : nil)
  @type = type
  @parent_id = parent_id
  @no_leaves = no_leaves == 'true' ? true : (no_leaves == 'false' ? false : nil)
  @exact = exact == 'true' ? true : (exact == 'false' ? false : nil)
  super
end

Instance Attribute Details

#exactBoolean

Returns &exact=<“true”|“false”> if 'true' then only #name = query_string results are returned (no fuzzy matching)

Returns:

  • (Boolean)

    &exact=<“true”|“false”> if 'true' then only #name = query_string results are returned (no fuzzy matching)



29
30
31
# File 'lib/queries/taxon_name/autocomplete.rb', line 29

def exact
  @exact
end

#no_leavesBoolean

Returns &no_leaves=<“true”|“false”> if 'true' then only names with descendents will be returned

Returns:

  • (Boolean)

    &no_leaves=<“true”|“false”> if 'true' then only names with descendents will be returned



34
35
36
# File 'lib/queries/taxon_name/autocomplete.rb', line 34

def no_leaves
  @no_leaves
end

#nomenclature_groupArray

and_clause

Returns:

  • (Array)


8
9
10
# File 'lib/queries/taxon_name/autocomplete.rb', line 8

def nomenclature_group
  @nomenclature_group
end

#parent_idArray

Returns &parent_id[]=<int>&parent_id=<other_int> etc.

Returns:

  • (Array)

    &parent_id[]=<int>&parent_id=<other_int> etc.



24
25
26
# File 'lib/queries/taxon_name/autocomplete.rb', line 24

def parent_id
  @parent_id
end

#typeArray

Returns &type[]=<Protonym, Combination, Hybrid, etc.>&type[]=<other type> etc.

Returns:

  • (Array)

    &type[]=<Protonym, Combination, Hybrid, etc.>&type[]=<other type> etc.



20
21
22
# File 'lib/queries/taxon_name/autocomplete.rb', line 20

def type
  @type
end

#validBoolean?

Returns &valid=<“true”|“false”>

if 'true'  then id == cached_valid_taxon_name_id
if 'false' then id != cached_valid_taxon_name
if nil   then no check made, i.e. all names

string is converted to Boolean here

Returns:

  • (Boolean, nil)

    &valid=<“true”|“false”>

    if 'true'  then id == cached_valid_taxon_name_id
    if 'false' then id != cached_valid_taxon_name
    if nil   then no check made, i.e. all names

    string is converted to Boolean here



16
17
18
# File 'lib/queries/taxon_name/autocomplete.rb', line 16

def valid
  @valid
end

Instance Method Details

#allScope

!! TODO: should be autocomplete and array …

Returns:

  • (Scope)


139
140
141
142
143
144
145
# File 'lib/queries/taxon_name/autocomplete.rb', line 139

def all
  ::TaxonName.select('taxon_names.*, char_length(taxon_names.cached)').
    includes(:ancestor_hierarchies).
    where(where_sql).
    references(:taxon_name_hierarchies).
    limit(dynamic_limit).order('char_length(taxon_names.cached), taxon_names.cached').distinct.all
end

#and_clausesArel:Nodes?

Returns:

  • (Arel:Nodes, nil)


69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/queries/taxon_name/autocomplete.rb', line 69

def and_clauses
  clauses = [
    valid_state,
    is_type,
    with_parent_id,
    with_nomenclature_group,
  ].compact

  return nil if clauses.nil?

  a = clauses.shift
  clauses.each do |b|
    a = a.and(b)
  end
  a
end

#authorshipString

Returns:

  • (String)


368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/queries/taxon_name/autocomplete.rb', line 368

def authorship
  parser = ::Biodiversity::Parser
  a = parser.parse(query_string)
  b = a
  return nil if b.nil? or b[:details].nil?

  b[:details].each do |detail|
    detail.each_value do |v|
      if v.kind_of?(Hash) && v[:authorship]
        return v[:authorship][:value]
      end
    end
  end
  nil
end

#autocompleteArray

rubocop:disable Metrics/MethodLength

Returns:

  • (Array)


308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/queries/taxon_name/autocomplete.rb', line 308

def autocomplete
  queries = (exact ? exact_autocomplete : comprehensive_autocomplete)
  queries.compact!

  result = []

  queries.each_with_index do |q,i|
    a = q
    a = q.where(project_id: project_id) if project_id
    a = a.where(and_clauses.to_sql) if and_clauses # TODO: duplicates clauses like exact!!
    a = a.not_leaves if no_leaves
    result += a.to_a
    break if result.count > 19
  end
  
  result.uniq!
  result[0..19]
end

#autocomplete_cached_author_yearScope

Returns:

  • (Scope)


241
242
243
244
# File 'lib/queries/taxon_name/autocomplete.rb', line 241

def autocomplete_cached_author_year
  a = table[:cached_author_year].matches("#{query_string.gsub(/[,\s]/, '%')}")
  base_query.where(a.to_sql).order('cached ASC').limit(20)
end

#autocomplete_cached_end_wildcardScope

Returns:

  • (Scope)


212
213
214
215
# File 'lib/queries/taxon_name/autocomplete.rb', line 212

def autocomplete_cached_end_wildcard
  a = table[:cached].matches("#{query_string}%")
  base_query.where(a.to_sql).limit(20)
end

#autocomplete_cached_name_end_wildcardScope

Returns:

  • (Scope)


218
219
220
221
# File 'lib/queries/taxon_name/autocomplete.rb', line 218

def autocomplete_cached_name_end_wildcard
  a = table[:name].matches("#{query_string}%")
  base_query.where(a.to_sql).limit(20)
end

#autocomplete_cached_wildcard_whitespaceScope

Returns:

  • (Scope)


224
225
226
227
# File 'lib/queries/taxon_name/autocomplete.rb', line 224

def autocomplete_cached_wildcard_whitespace
  a = table[:cached].matches("#{query_string.gsub('. ', ' ').gsub(' ', '%')}")
  base_query.where(a.to_sql).limit(20)
end

#autocomplete_exact_cachedScope

Returns:

  • (Scope)


148
149
150
151
# File 'lib/queries/taxon_name/autocomplete.rb', line 148

def autocomplete_exact_cached
  a = table[:cached].eq(query_string)
  base_query.where(a.to_sql).order('cached_author_year ASC').limit(20)
end

#autocomplete_exact_cached_original_combinationScope

Returns:

  • (Scope)


154
155
156
157
# File 'lib/queries/taxon_name/autocomplete.rb', line 154

def autocomplete_exact_cached_original_combination
  a = table[:cached_original_combination].eq(query_string)
  base_query.where(a.to_sql).order('cached_author_year ASC').limit(20)
end

#autocomplete_exact_name_and_yearScope

Returns:

  • (Scope)


166
167
168
169
170
171
172
173
174
175
# File 'lib/queries/taxon_name/autocomplete.rb', line 166

def autocomplete_exact_name_and_year
  a = alphabetic_strings
  b = years
  if a.size == 1 && !b.empty?
    a = table[:name].eq(a.first).and(table[:cached_author_year].matches_any(wildcard_wrapped_years))
    base_query.where(a.to_sql).limit(10)
  else
    nil
  end
end

#autocomplete_genus_species1(result) ⇒ Scope

Parameters:

  • result (String)

Returns:

  • (Scope)


197
198
199
200
201
# File 'lib/queries/taxon_name/autocomplete.rb', line 197

def autocomplete_genus_species1(result)
  return nil if result.nil?
  a = table[:cached].matches(result)
  base_query.where(a.to_sql).order('type DESC, cached ASC').limit(8)
end

#autocomplete_genus_species2(result) ⇒ Scope

Parameters:

  • result (String)

Returns:

  • (Scope)


205
206
207
208
209
# File 'lib/queries/taxon_name/autocomplete.rb', line 205

def autocomplete_genus_species2(result)
  return nil if result.nil?
  a = table[:cached].matches(result + '%')
  base_query.where(a.to_sql).order('type DESC, cached ASC').limit(8)
end

#autocomplete_name_author_year_fragmentScope?

Returns:

  • (Scope, nil)


230
231
232
233
234
235
236
237
238
# File 'lib/queries/taxon_name/autocomplete.rb', line 230

def autocomplete_name_author_year_fragment
  f = fragments
  if f.size == 2
    a = table[:name].matches(f[0]).and(table[:cached_author_year].matches(f[1]))
    base_query.where(a.to_sql).limit(20)
  else
    nil
  end
end

#autocomplete_taxon_name_author_year_matchesArel::Nodes::Matches

Returns:

  • (Arel::Nodes::Matches)


261
262
263
264
265
# File 'lib/queries/taxon_name/autocomplete.rb', line 261

def autocomplete_taxon_name_author_year_matches
  a = authorship
  return nil if a.nil?
  base_query.where(table[:cached_author_year].matches(a).to_sql).limit(10)
end

#autocomplete_top_cachedScope

Returns:

  • (Scope)


184
185
186
187
# File 'lib/queries/taxon_name/autocomplete.rb', line 184

def autocomplete_top_cached
  a = table[:cached].matches("#{query_string}")
  base_query.where(a.to_sql).limit(1)
end

#autocomplete_top_cached_subgenusScope

Returns:

  • (Scope)


190
191
192
193
# File 'lib/queries/taxon_name/autocomplete.rb', line 190

def autocomplete_top_cached_subgenus
  a = table[:cached].matches("%(#{query_string})")
  base_query.where(a.to_sql).limit(1)
end

#autocomplete_top_nameScope

Returns:

  • (Scope)


178
179
180
181
# File 'lib/queries/taxon_name/autocomplete.rb', line 178

def autocomplete_top_name
  a = table[:name].eq(query_string)
  base_query.where(a.to_sql).order('cached_author_year ASC').limit(20)
end

#autocomplete_wildcard_author_year_joined_piecesScope?

Returns:

  • (Scope, nil)


247
248
249
250
251
# File 'lib/queries/taxon_name/autocomplete.rb', line 247

def autocomplete_wildcard_author_year_joined_pieces
  return nil if pieces.empty?
  a = table[:cached_author_year].matches("%#{pieces.join('%')}%")
  base_query.where(a.to_sql).order('cached ASC').limit(20)
end

#autocomplete_wildcard_cached_original_combinationScope

Returns:

  • (Scope)


160
161
162
163
# File 'lib/queries/taxon_name/autocomplete.rb', line 160

def autocomplete_wildcard_cached_original_combination
  a = table[:cached_original_combination].matches(wildcard_pieces)
  base_query.where(a.to_sql).order('cached_author_year ASC').limit(20)
end

#autocomplete_wildcard_joined_stringsScope?

Returns:

  • (Scope, nil)


254
255
256
257
258
# File 'lib/queries/taxon_name/autocomplete.rb', line 254

def autocomplete_wildcard_joined_strings
  return nil if alphabetic_strings.empty?
  a = table[:cached].matches("%#{alphabetic_strings.join('%')}%")
  base_query.where(a.to_sql).limit(10)
end

#base_queryScope

Returns:

  • (Scope)


346
347
348
349
350
# File 'lib/queries/taxon_name/autocomplete.rb', line 346

def base_query
  ::TaxonName.select('taxon_names.*, char_length(taxon_names.cached)').
    includes(:ancestor_hierarchies).
    order(Arel.sql('char_length(taxon_names.cached), taxon_names.cached ASC'))
end

#comprehensive_autocompleteObject



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/queries/taxon_name/autocomplete.rb', line 279

def comprehensive_autocomplete
  z = genus_species

  queries = [
    autocomplete_exact_cached,
    autocomplete_exact_cached_original_combination,
    autocomplete_identifier_cached_exact, 
    autocomplete_exact_name_and_year,
    autocomplete_identifier_identifier_exact,
    autocomplete_top_name,
    autocomplete_top_cached,
    autocomplete_top_cached_subgenus, # not tested
    autocomplete_genus_species1(z),   # not tested
    autocomplete_genus_species2(z),   # not tested
    autocomplete_cached_end_wildcard,
    autocomplete_identifier_cached_like,
    autocomplete_cached_name_end_wildcard,
    autocomplete_cached_wildcard_whitespace,
    autocomplete_name_author_year_fragment,
    autocomplete_taxon_name_author_year_matches,
    autocomplete_cached_author_year,
    autocomplete_wildcard_joined_strings,
    autocomplete_wildcard_author_year_joined_pieces,
    autocomplete_wildcard_cached_original_combination
  ]
end

#exact_autocompleteObject

Used in new taxon name, for example



268
269
270
271
272
273
274
275
276
277
# File 'lib/queries/taxon_name/autocomplete.rb', line 268

def exact_autocomplete
  [
    autocomplete_exact_cached,
    autocomplete_exact_cached_original_combination,
    autocomplete_exact_name_and_year,
    autocomplete_top_name,
    autocomplete_top_cached,
    autocomplete_cached_end_wildcard
  ]
end

#genus_speciesString?

Returns parse and only return what is assumed to be genus/species, with a wildcard in front

Returns:

  • (String, nil)

    parse and only return what is assumed to be genus/species, with a wildcard in front



330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/queries/taxon_name/autocomplete.rb', line 330

def genus_species
  p = TaxonWorks::Vendor::Biodiversity::Result.new
  p.name = query_string
  r = p.parse

  a = p.genus
  b = p.species

  if a && b
    a + '%' + b
  else
    nil
  end
end

#is_typeArel::Nodes::<>?

and clause

Returns:

  • (Arel::Nodes::<>, nil)


112
113
114
115
# File 'lib/queries/taxon_name/autocomplete.rb', line 112

def is_type
  return nil if type.empty?
  table[:type].eq_any(type)
end

#or_andArel:Nodes

Returns:

  • (Arel:Nodes)


87
88
89
90
91
92
93
94
95
96
# File 'lib/queries/taxon_name/autocomplete.rb', line 87

def or_and
  a = or_clauses
  b = and_clauses

  if a && b
    a.and(b)
  else
    a
  end
end

#or_clausesArel:Nodes

Returns:

  • (Arel:Nodes)


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/queries/taxon_name/autocomplete.rb', line 48

def or_clauses
  clauses = []

  clauses.push exactly_named if exact

  clauses += [
    only_ids,
    cached,
    with_cached_author_year,
  ] unless exact

  clauses.compact!

  a = clauses.shift
  clauses.each do |b|
    a = a.or(b)
  end
  a
end

#tableArel::Table

Returns:

  • (Arel::Table)


353
354
355
# File 'lib/queries/taxon_name/autocomplete.rb', line 353

def table
  ::TaxonName.arel_table
end

#taxon_name_hierarchies_tableArel::Table

Returns:

  • (Arel::Table)


358
359
360
# File 'lib/queries/taxon_name/autocomplete.rb', line 358

def taxon_name_hierarchies_table
  Arel::Table.new('taxon_name_hierarchies')
end

#valid_stateArel::Nodes::<>?

and clause

Returns:

  • (Arel::Nodes::<>, nil)


105
106
107
108
# File 'lib/queries/taxon_name/autocomplete.rb', line 105

def valid_state
  return nil if @valid.nil?
  valid ? table[:id].eq(table[:cached_valid_taxon_name_id]) : table[:id].not_eq(table[:cached_valid_taxon_name_id])
end

#where_sqlString

Returns:

  • (String)


99
100
101
# File 'lib/queries/taxon_name/autocomplete.rb', line 99

def where_sql
  with_project_id.and(or_and).to_sql
end

#with_cached_author_yearArel::Nodes::Matches

Returns:

  • (Arel::Nodes::Matches)


363
364
365
# File 'lib/queries/taxon_name/autocomplete.rb', line 363

def with_cached_author_year
  table[:cached_author_year].matches_any(terms)
end

#with_nomenclature_groupArel::Nodes::Grouping?

Returns and clause

Returns:

  • (Arel::Nodes::Grouping, nil)

    and clause



126
127
128
129
# File 'lib/queries/taxon_name/autocomplete.rb', line 126

def with_nomenclature_group
  return nil if nomenclature_group.empty?
  table[:rank_class].matches_any(nomenclature_group)
end

#with_parent_idArel::Nodes::<>?

and clause, limit to ancestors or [ids]

Returns:

  • (Arel::Nodes::<>, nil)


119
120
121
122
# File 'lib/queries/taxon_name/autocomplete.rb', line 119

def with_parent_id
  return nil if parent_id.empty?
  taxon_name_hierarchies_table[:ancestor_id].eq_any(parent_id)
end