Class: Queries::Extract::Filter

Inherits:
Query::Filter show all
Includes:
Concerns::Citations, Concerns::Confidences, Concerns::Containable, Concerns::DataAttributes, Concerns::DateRanges, Concerns::Protocols, Concerns::Tags, Helpers
Defined in:
lib/queries/extract/filter.rb

Constant Summary collapse

PARAMS =
[
  :collection_object_id,
  :descendants,
  :exact_verbatim_anatomical_origin,
  :extract_end_date_range,
  :extract_id,
  :extract_origin,
  :extract_start_date_range,
  :otu_id,
  :protocol_id,
  :repository_id,
  :sequences,
  :taxon_name_id,
  :verbatim_anatomical_origin,
  collection_object_id: [],
  extract_id: [],
  otu_id: [],
  repository_id: [],
  taxon_name_id: [],
].freeze

Constants inherited from Query::Filter

Query::Filter::FILTER_QUERIES, Query::Filter::SUBQUERIES

Instance Attribute Summary collapse

Attributes inherited from Query::Filter

#anatomical_part_query, #api, #asserted_distribution_query, #biological_association_query, #biological_associations_graph_query, #collecting_event_query, #collection_object_query, #content_query, #controlled_vocabulary_term_query, #conveyance_query, #data_attribute_query, #depiction_query, #descriptor_query, #document_query, #dwc_occurrence_query, #extract_query, #field_occurrence_query, #image_query, #loan_query, #object_global_id, #observation_query, #order_by, #otu_query, #page, #paginate, #params, #per, #person_query, #project_id, #recent, #recent_target, #roll_call, #sound_query, #taxon_name_query, #taxon_name_relationship_query, #venn, #venn_ignore_pagination, #venn_mode

Attributes inherited from Query

#query_string, #terms

Instance Method Summary collapse

Methods included from Helpers

#boolean_param, #integer_param, #split_pairs, #split_repeated_pairs, #tri_value_array

Methods inherited from Query::Filter

#all, #all_and_clauses, #all_merge_clauses, #annotator_and_clauses, #annotator_merge_clauses, annotator_params, api_except_params, api_excluded_params, #apply_venn, #attribute_exact_facet, base_filter, base_query_name, base_query_to_h, #deep_permit, #disable_paging, included_annotator_facets, instantiated_base_filter, inverted_subqueries, #model_id_facet, #object_global_id_facet, #only_project?, #only_project_or_less?, #paging_state, params, #permitted_params, #process_url_into_params, #project_id_facet, query_name, #set_nested_queries, #set_paging, set_paging, #shared_and_clauses, #subquery_vector, #target_and_clauses, #venn_query

Methods inherited from Query

#alphabetic_strings, #alphanumeric_strings, base_name, #base_name, #base_query, #build_terms, #cached_facet, #end_wildcard, #levenshtein_distance, #match_ordered_wildcard_pieces_in_cached, #no_terms?, referenced_klass, #referenced_klass, #referenced_klass_except, #referenced_klass_intersection, #referenced_klass_union, #start_and_end_wildcard, #start_wildcard, #table, #wildcard_pieces

Constructor Details

#initialize(query_params) ⇒ Filter

Returns a new instance of Filter.

Parameters:

  • args (Hash)

    are permitted params



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/queries/extract/filter.rb', line 84

def initialize(query_params)
  super

  @collection_object_id = params[:collection_object_id]
  @descendants = boolean_param(params, :descendants)
  @exact_verbatim_anatomical_origin = params[:exact_verbatim_anatomical_origin]
  @extract_end_date_range = params[:extract_end_date_range]
  @extract_origin = params[:extract_origin]
  @extact_id = params[:extract_id]
  @extract_start_date_range = params[:extract_start_date_range]
  @otu_id = params[:otu_id]
  @repository_id = params[:repository_id]
  @sequences = boolean_param(params, :sequences)
  @taxon_name_id = params[:taxon_name_id]
  @verbatim_anatomical_origin = params[:verbatim_anatomical_origin]

  set_confidences_params(params)
  set_containable_params(params)
  set_citations_params(params)
  set_data_attributes_params(params)
  set_date_params(params)
  set_tags_params(params)
  set_protocols_params(params)
end

Instance Attribute Details

#collection_object_idArray of Repository#id

Returns:



42
43
44
# File 'lib/queries/extract/filter.rb', line 42

def collection_object_id
  @collection_object_id
end

#descendantsObject

Returns the value of attribute descendants.



48
49
50
# File 'lib/queries/extract/filter.rb', line 48

def descendants
  @descendants
end

#exact_verbatim_anatomical_originBoolean?

Parameters:

  • extract_anatomical_origin (String)

    'true', 'false', nil

Returns:

  • (Boolean, nil)


76
77
78
# File 'lib/queries/extract/filter.rb', line 76

def exact_verbatim_anatomical_origin
  @exact_verbatim_anatomical_origin
end

#extract_end_date_rangeDate? (private)

Parameters:

  • extract_end_date_range (String)

    yyyy-mm-dd

Returns:

  • (Date, nil)


58
59
60
# File 'lib/queries/extract/filter.rb', line 58

def extract_end_date_range
  @extract_end_date_range
end

#extract_idObject

Returns Array.

Parameters:

  • extract_id (Numeric, String, Array)

    a set of extract#id

Returns:

  • Array



81
82
83
# File 'lib/queries/extract/filter.rb', line 81

def extract_id
  @extract_id
end

#extract_originString?

Parameters:

  • see (String)

    originates_from in app/models/extract.rb for legal values

Returns:

  • (String, nil)


67
68
69
# File 'lib/queries/extract/filter.rb', line 67

def extract_origin
  @extract_origin
end

#extract_start_date_rangeDate? (private)

Parameters:

  • extract_start_date_range (String)

    yyyy-mm-dd

Returns:

  • (Date, nil)


53
54
55
# File 'lib/queries/extract/filter.rb', line 53

def extract_start_date_range
  @extract_start_date_range
end

#otu_idArray of Repository#id

Returns:



39
40
41
# File 'lib/queries/extract/filter.rb', line 39

def otu_id
  @otu_id
end

#repository_idArray of Repository#id

Returns:



36
37
38
# File 'lib/queries/extract/filter.rb', line 36

def repository_id
  @repository_id
end

#sequencesBoolean

Parameters:

  • (String, Boolean, nil)

Returns:

  • (Boolean)


62
63
64
# File 'lib/queries/extract/filter.rb', line 62

def sequences
  @sequences
end

#taxon_name_idProtonym.id?

Return all extracts linked to OTUs AND CollectionObject that is self or descendant linked to this TaxonName

Returns:

  • (Protonym.id, nil)

    return all extracts linked to OTUs AND CollectionObject that is self or descendant linked to this TaxonName



47
48
49
# File 'lib/queries/extract/filter.rb', line 47

def taxon_name_id
  @taxon_name_id
end

#verbatim_anatomical_originString?

Parameters:

  • anatomical_origin (String)

Returns:

  • (String, nil)


71
72
73
# File 'lib/queries/extract/filter.rb', line 71

def verbatim_anatomical_origin
  @verbatim_anatomical_origin
end

Instance Method Details

#anatomical_part_query_facetObject



266
267
268
269
270
271
272
# File 'lib/queries/extract/filter.rb', line 266

def anatomical_part_query_facet
  return nil if anatomical_part_query.nil?

  ::Extract
    .joins(:related_origin_relationships)
    .where("origin_relationships.old_object_id IN (#{ anatomical_part_query.all.select(:id).to_sql })")
end

#and_clausesArray

Returns:

  • (Array)


275
276
277
278
279
280
281
282
# File 'lib/queries/extract/filter.rb', line 275

def and_clauses
  [
    extract_id_facet,
    attribute_exact_facet(:verbatim_anatomical_origin),
    date_made_facet,
    repository_id_facet,
  ]
end

#collection_object_id_facetObject



198
199
200
201
# File 'lib/queries/extract/filter.rb', line 198

def collection_object_id_facet
  return nil if collection_object_id.empty?
  ::Extract.joins(:origin_collection_objects).where(collection_objects: {id: collection_object_id})
end

#collection_object_query_facetObject



243
244
245
246
247
248
249
250
251
252
# File 'lib/queries/extract/filter.rb', line 243

def collection_object_query_facet
  return nil if collection_object_query.nil?
  s = 'WITH query_co_exs AS (' + collection_object_query.all.to_sql + ') ' +
    ::Extract
    .joins(:origin_collection_objects)
    .joins('JOIN query_co_exs as query_co_exs1 on collection_objects.id = query_co_exs1.id')
    .to_sql

  ::Extract.from('(' + s + ') as extracts')
end

#date_made_facetObject

TODO: Abstract to single date store range helper



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/queries/extract/filter.rb', line 163

def date_made_facet
  return nil if extract_start_date_range.nil?
  a = extract_start_date_range
  sy,sm,sd = a.year, a.month, a.day
  b = extract_end_date_range
  ey,em,ed = b.year, b.month, b.day

  # 5 possible ranges to consider

  ranges = []

  if sy < ey
    # b/w years
    ranges.push table[:year_made].gt(sy).and(table[:year_made].lt(ey))

    # b/w months start
    ranges.push table[:year_made].eq(sy).and(table[:month_made].gt(sm))

    # b/w months end
    ranges.push table[:year_made].eq(ey).and(table[:month_made].lt(em))
  end

  # days in start month
  ranges.push table[:year_made].eq(sy).and(table[:month_made].eq(sm)).and(table[:day_made].gteq(sd)).and(table[:day_made].lteq(ed))

  # days in end month
  ranges.push table[:year_made].eq(ey).and(table[:month_made].eq(em)).and(table[:day_made].lteq(ed))

  a = ranges.shift
  ranges.each do |r|
    a = a.or(r)
  end
  a
end

#extract_id_facetObject



129
130
131
132
# File 'lib/queries/extract/filter.rb', line 129

def extract_id_facet
  return nil if extract_id.empty?
  table[:id].in(extract_id)
end

#extract_origin_facetObject



147
148
149
150
# File 'lib/queries/extract/filter.rb', line 147

def extract_origin_facet
  return nil if extract_origin.nil?
  ::Extract.joins(:related_origin_relationships).where(origin_relationships: {old_object_type: extract_origin})
end

#merge_clausesObject



284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/queries/extract/filter.rb', line 284

def merge_clauses
  [
    anatomical_part_query_facet,
    observation_query_facet,
    collection_object_query_facet,
    otu_query_facet,

    collection_object_id_facet,
    extract_origin_facet,
    otu_id_facet,
    sequences_facet,
    taxon_name_id_facet,
  ]
end

#observation_query_facetObject



255
256
257
258
259
260
261
262
263
264
# File 'lib/queries/extract/filter.rb', line 255

def observation_query_facet
  return nil if observation_query.nil?
  s = 'WITH query_obs_extracts AS (' + observation_query.all.to_sql + ') ' +
      ::Extract
        .joins(:observations)
        .joins('JOIN query_obs_extracts as query_obs_extracts1 on observations.id = query_obs_extracts1.id')
        .to_sql

  ::Extract.from('(' + s + ') as extracts').distinct
end

#otu_id_facetObject



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

def otu_id_facet
  return nil if otu_id.empty?
  a = ::Extract.joins(:origin_otus).where(otus: {id: otu_id})
  b = ::Extract.joins(origin_collection_objects: [:otus]).where(otus: {id: otu_id})

  ::Extract.from("((#{a.to_sql}) UNION (#{b.to_sql})) as extracts")
end

#otu_query_facetObject

!! Targets origins of both Otu, and Determined specimens



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/queries/extract/filter.rb', line 223

def otu_query_facet
  return nil if otu_query.nil?
  w = 'WITH query_otu_exs_a AS (' + otu_query.all.to_sql + ') '

  u1 = ::Extract
    .joins(:origin_otus)
    .joins('JOIN query_otu_exs_a as query_otu_exs_a1 on otus.id = query_otu_exs_a1.id')
    .to_sql

  u2 = ::Extract
    .joins(origin_collection_objects: [:taxon_determinations])
    .joins('JOIN query_otu_exs_a as query_otu_exs_a2 on taxon_determinations.otu_id = query_otu_exs_a2.id')
    .where('taxon_determinations.position = 1')
    .to_sql

  s = w + ::Extract.from("((#{u1}) UNION (#{u2})) as extracts").to_sql

  ::Extract.from('(' + s + ') as extracts')
end

#repository_id_facetObject



134
135
136
137
# File 'lib/queries/extract/filter.rb', line 134

def repository_id_facet
  return nil if repository_id.empty?
  table[:repository_id].in(repository_id)
end

#sequences_facetObject



152
153
154
155
156
157
158
159
160
# File 'lib/queries/extract/filter.rb', line 152

def sequences_facet
  return nil if sequences.nil?

  subquery = ::OriginRelationship.where(
    ::OriginRelationship.arel_table[:old_object_id].eq(table[:id])
    .and(::OriginRelationship.arel_table[:new_object_type].eq('Sequence')))
    .arel.exists
  ::Extract.where(sequences ? subquery : subquery.not)
end

#taxon_name_id_facetObject

TODO: with() TODO: this is not a join, but an IN x2 UNION, i.e. there is likely room for optimization via a join.



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/queries/extract/filter.rb', line 206

def taxon_name_id_facet
  return nil if taxon_name_id.empty?

  o = nil
  if descendants
    o = ::Otu.descendant_of_taxon_name(taxon_name_id)
  else
    o = ::Otu.where(taxon_name_id:)
  end

  a = ::Extract.joins(:origin_otus).where(otus: o)
  b = ::Extract.joins(:origin_collection_objects).where(collection_objects: ::CollectionObject.joins(:otus).where(otus: o))

  ::Extract.from("((#{a.to_sql}) UNION (#{b.to_sql})) as extracts")
end