Class: Cocina::Models::Builders::TitleBuilder

Inherits:
Object
  • Object
show all
Extended by:
Deprecation
Defined in:
lib/cocina/models/builders/title_builder.rb

Overview

TitleBuilder selects the prefered title from the cocina object for solr indexing

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(strategy:, add_punctuation:, only_one_parallel_value: true, part_label: nil) ⇒ TitleBuilder

Returns a new instance of TitleBuilder.

Parameters:

  • strategy (Symbol)

    “:first” selects a single title value based on precedence of primary, untyped, first occurrence. “:all” returns an array containing all the values.

  • add_punctuation (boolean)

    whether the title should be formmated with punctuation (think of a structured value coming from a MARC record, which is designed for catalog cards.)

  • only_one_parallel_value (boolean) (defaults to: true)

    when true, choose one of the parallel values according to precedence of primary, untyped, first occurrence. When false, return an array containing all the parallel values. Why? Think of e.g. title displayed in blacklight search results vs boosting values for ranking of search results

  • part_label (String) (defaults to: nil)

    the partLabel to add for digital serials display



65
66
67
68
69
70
# File 'lib/cocina/models/builders/title_builder.rb', line 65

def initialize(strategy:, add_punctuation:, only_one_parallel_value: true, part_label: nil)
  @strategy = strategy
  @add_punctuation = add_punctuation
  @only_one_parallel_value = only_one_parallel_value
  @part_label = part_label
end

Class Method Details

.additional_titles(titles) ⇒ Array<String>

“additional titles” are all title data except for full_title. We want to able able to index it separately so

we can boost matches on it in search results (boost matching these strings lower than other titles present)

Parameters:

Returns:

  • (Array<String>)

    the values for Solr



52
53
54
# File 'lib/cocina/models/builders/title_builder.rb', line 52

def self.additional_titles(titles)
  [new(strategy: :all, add_punctuation: false).build(titles)].flatten - full_title(titles)
end

.build(titles, catalog_links: [], strategy: :first, add_punctuation: true) ⇒ String, Array

Returns the title value for Solr - for :first strategy, a string; for :all strategy, an array (e.g. title displayed in blacklight search results vs boosting values for search result rankings).

Parameters:

  • titles (Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>)

    the titles to consider

  • catalog_links (Array<Cocina::Models::FolioCatalogLink>) (defaults to: [])

    the folio catalog links to check for digital serials part labels

  • strategy (Symbol) (defaults to: :first)

    “:first” is the strategy for selection when primary or display title are missing

  • add_punctuation (Boolean) (defaults to: true)

    determines if the title should be formmated with punctuation

Returns:

  • (String, Array)

    the title value for Solr - for :first strategy, a string; for :all strategy, an array (e.g. title displayed in blacklight search results vs boosting values for search result rankings)



18
19
20
21
22
23
24
25
26
27
# File 'lib/cocina/models/builders/title_builder.rb', line 18

def self.build(titles, catalog_links: [], strategy: :first, add_punctuation: true)
  part_label = catalog_links.find { |link| link.catalog == 'folio' }&.partLabel
  if titles.respond_to?(:description)
    Deprecation.warn(self,
                     "Calling TitleBuilder.build with a #{titles.class} is deprecated. " \
                     'It must be called with an array of titles')
    titles = titles.description.title
  end
  new(strategy: strategy, add_punctuation: add_punctuation, part_label: part_label).build(titles)
end

.full_title(titles, catalog_links: []) ⇒ Array<String>

the “full title” is the title WITH subtitle, part name, etc. We want to able able to index it separately so

we can boost matches on it in search results (boost matching this string higher than other titles present)

Parameters:

Returns:

  • (Array<String>)

    the full title value(s) for Solr - array due to possible parallelValue



43
44
45
46
# File 'lib/cocina/models/builders/title_builder.rb', line 43

def self.full_title(titles, catalog_links: [])
  part_label = catalog_links.find { |link| link.catalog == 'folio' }&.partLabel
  [new(strategy: :first, add_punctuation: false, only_one_parallel_value: false, part_label: part_label).build(titles)].flatten.compact
end

.main_title(titles) ⇒ Array<String>

the “main title” is the title withOUT subtitle, part name, etc. We want to index it separately so

we can boost matches on it in search results (boost matching this string higher than matching full title string)
e.g. "The Hobbit" (main_title) vs "The Hobbit, or, There and Back Again (full_title)

Parameters:

Returns:

  • (Array<String>)

    the main title value(s) for Solr - array due to possible parallelValue



34
35
36
# File 'lib/cocina/models/builders/title_builder.rb', line 34

def self.main_title(titles)
  new(strategy: :first, add_punctuation: false).main_title(titles)
end

Instance Method Details

#build(cocina_titles) ⇒ String, Array

rubocop:disable Metrics/PerceivedComplexity

Parameters:

Returns:

  • (String, Array)

    the title value for Solr - for :first strategy, a string; for :all strategy, an array (e.g. title displayed in blacklight search results vs boosting values for search result rankings)



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/cocina/models/builders/title_builder.rb', line 77

def build(cocina_titles)
  cocina_title = primary_title(cocina_titles) || untyped_title(cocina_titles)
  cocina_title = other_title(cocina_titles) if cocina_title.blank?
  if strategy == :first
    result = extract_title(cocina_title)
    result = add_part_label(result) if part_label.present?
    result
  else
    result = cocina_titles.map { |ctitle| extract_title(ctitle) }.flatten
    if only_one_parallel_value? && result.length == 1
      result.first
    else
      result
    end
  end
end

#main_title(titles) ⇒ Array<String>

this is the single “short title” - the title without subtitle, part name, etc.

this may be useful for boosting and exact matching for search results

Returns:

  • (Array<String>)

    the main title value(s) for Solr - can be array due to parallel titles



98
99
100
101
102
103
# File 'lib/cocina/models/builders/title_builder.rb', line 98

def main_title(titles)
  cocina_title = primary_title(titles) || untyped_title(titles)
  cocina_title = other_title(titles) if cocina_title.blank?

  extract_main_title(cocina_title)
end