Class: Queries::Extract::Filter

Inherits:
Query::Filter show all
Includes:
Concerns::Citations, Concerns::Containable, 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

#api, #asserted_distribution_query, #biological_association_query, #biological_associations_graph_query, #collecting_event_query, #collection_object_query, #content_query, #controlled_vocabulary_term_query, #data_attribute_query, #descriptor_query, #extract_query, #field_occurrence_query, #image_query, #loan_query, #object_global_id, #observation_query, #otu_query, #page, #paginate, #params, #per, #person_query, #project_id, #recent, #taxon_name_query, #venn, #venn_mode

Attributes inherited from Query

#query_string, #terms

Instance Method Summary collapse

Methods included from Helpers

#boolean_param

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, #deep_permit, included_annotator_facets, inverted_subqueries, #model_id_facet, #object_global_id_facet, params, #permitted_params, #process_url_into_params, #project_id_facet, query_name, #query_name, #set_nested_queries, #shared_and_clauses, #subquery_vector, #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



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

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_containable_params(params)
  set_citations_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:



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

def collection_object_id
  @collection_object_id
end

#descendantsObject

Returns the value of attribute descendants.



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

def descendants
  @descendants
end

#exact_verbatim_anatomical_originBoolean?

Parameters:

  • extract_anatomical_origin (String)

    ‘true’, ‘false’, nil

Returns:

  • (Boolean, nil)


74
75
76
# File 'lib/queries/extract/filter.rb', line 74

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)


56
57
58
# File 'lib/queries/extract/filter.rb', line 56

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



79
80
81
# File 'lib/queries/extract/filter.rb', line 79

def extract_id
  @extract_id
end

#extract_originString?

Parameters:

  • see (String)

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

Returns:

  • (String, nil)


65
66
67
# File 'lib/queries/extract/filter.rb', line 65

def extract_origin
  @extract_origin
end

#extract_start_date_rangeDate? (private)

Parameters:

  • extract_start_date_range (String)

    yyyy-mm-dd

Returns:

  • (Date, nil)


51
52
53
# File 'lib/queries/extract/filter.rb', line 51

def extract_start_date_range
  @extract_start_date_range
end

#otu_idArray of Repository#id

Returns:



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

def otu_id
  @otu_id
end

#repository_idArray of Repository#id

Returns:



34
35
36
# File 'lib/queries/extract/filter.rb', line 34

def repository_id
  @repository_id
end

#sequencesBoolean

Parameters:

  • (String, Boolean, nil)

Returns:

  • (Boolean)


60
61
62
# File 'lib/queries/extract/filter.rb', line 60

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



45
46
47
# File 'lib/queries/extract/filter.rb', line 45

def taxon_name_id
  @taxon_name_id
end

#verbatim_anatomical_originString?

Parameters:

  • anatomical_origin (String)

Returns:

  • (String, nil)


69
70
71
# File 'lib/queries/extract/filter.rb', line 69

def verbatim_anatomical_origin
  @verbatim_anatomical_origin
end

Instance Method Details

#and_clausesArray

Returns:

  • (Array)


263
264
265
266
267
268
269
270
# File 'lib/queries/extract/filter.rb', line 263

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

#collection_object_id_facetObject



194
195
196
197
# File 'lib/queries/extract/filter.rb', line 194

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



239
240
241
242
243
244
245
246
247
248
# File 'lib/queries/extract/filter.rb', line 239

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



159
160
161
162
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
# File 'lib/queries/extract/filter.rb', line 159

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



125
126
127
128
# File 'lib/queries/extract/filter.rb', line 125

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

#extract_origin_facetObject



143
144
145
146
# File 'lib/queries/extract/filter.rb', line 143

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



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

def merge_clauses
  [
    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



251
252
253
254
255
256
257
258
259
260
# File 'lib/queries/extract/filter.rb', line 251

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



135
136
137
138
139
140
141
# File 'lib/queries/extract/filter.rb', line 135

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



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/queries/extract/filter.rb', line 219

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



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

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

#sequences_facetObject



148
149
150
151
152
153
154
155
156
# File 'lib/queries/extract/filter.rb', line 148

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.



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/queries/extract/filter.rb', line 202

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