|
1 | 1 | module PublishingApiAction |
2 | 2 | class Publish < Base |
3 | | - # All the possible keys in the message hash that can contain the primary unstructured document |
4 | | - # content that we want to index, represented as JsonPath path strings. |
5 | | - INDEXABLE_CONTENT_VALUES_JSON_PATHS = %w[ |
6 | | - $.details.description |
7 | | - $.details.introduction |
8 | | - $.details.introductory_paragraph |
9 | | - $.details.contact_groups[*].title |
10 | | - $.details.title |
11 | | - $.details.summary |
12 | | - $.details.body |
13 | | - $.details.need_to_know |
14 | | - $.details.more_information |
15 | | - ].map { JsonPath.new(_1, use_symbols: true) }.freeze |
16 | | - INDEXABLE_CONTENT_SEPARATOR = "\n".freeze |
17 | | - |
18 | | - # All the possible keys in the message hash that can contain additional keywords or other text |
19 | | - # that should be searchable but doesn't form part of the primary document content, represented |
20 | | - # as JsonPath path strings. |
21 | | - ADDITIONAL_SEARCHABLE_TEXT_VALUES_JSON_PATHS = %w[ |
22 | | - $.details.hidden_search_terms |
23 | | - $.details.metadata.hidden_indexable_content |
24 | | - $.details.metadata.project_code |
25 | | - $.details.metadata.aircraft_type |
26 | | - $.details.metadata.registration |
27 | | - $.details.metadata.tribunal_decision_categories_name |
28 | | - $.details.metadata.tribunal_decision_country_name |
29 | | - $.details.metadata.tribunal_decision_judges_name |
30 | | - $.details.metadata.tribunal_decision_category_name |
31 | | - $.details.metadata.tribunal_decision_sub_category_name |
32 | | - $.details.metadata.tribunal_decision_sub_categories_name |
33 | | - $.details.metadata.tribunal_decision_landmark_name |
34 | | - $.details.acronym |
35 | | - $.details.attachments[*]['title','isbn','unique_reference','command_paper_number','hoc_paper_number'] |
36 | | - ].map { JsonPath.new(_1, use_symbols: true) }.freeze |
37 | | - ADDITIONAL_SEARCHABLE_TEXT_VALUES_SEPARATOR = "\n".freeze |
| 3 | + include ::PublishingApi::Metadata |
| 4 | + include ::PublishingApi::Content |
38 | 5 |
|
39 | 6 | # Synchronize the document to the given service (i.e. create or update it remotely) |
40 | 7 | def synchronize(service: DiscoveryEngine::Put.new) |
41 | 8 | service.call(content_id, metadata, content:, payload_version:) |
42 | 9 | end |
43 | | - |
44 | | - # Extracts a hash of structured metadata about this document. |
45 | | - def metadata |
46 | | - { |
47 | | - content_id: document_hash[:content_id], |
48 | | - title: document_hash[:title], |
49 | | - description: document_hash[:description], |
50 | | - additional_searchable_text:, |
51 | | - link:, |
52 | | - url:, |
53 | | - public_timestamp:, |
54 | | - document_type: document_hash[:document_type], |
55 | | - content_purpose_supergroup: document_hash[:content_purpose_supergroup], |
56 | | - part_of_taxonomy_tree: document_hash.dig(:links, :taxons) || [], |
57 | | - # Vertex can only currently boost on numeric fields, not booleans |
58 | | - is_historic: historic? ? 1 : 0, |
59 | | - government_name:, |
60 | | - organisation_state:, |
61 | | - locale: document_hash[:locale], |
62 | | - parts:, |
63 | | - }.compact |
64 | | - end |
65 | | - |
66 | | - # Extracts a single string of indexable unstructured content from the document. |
67 | | - def content |
68 | | - values_from_json_paths = INDEXABLE_CONTENT_VALUES_JSON_PATHS.map { _1.on(document_hash) } |
69 | | - values_from_parts = document_hash.dig(:details, :parts)&.map do |
70 | | - # Add the part title as a heading to help the search model better understand the structure |
71 | | - # of the content |
72 | | - ["<h1>#{_1[:title]}</h1>", ContentWithMultipleTypes.new(_1[:body]).html_content] |
73 | | - end |
74 | | - |
75 | | - [ |
76 | | - *values_from_json_paths, |
77 | | - *values_from_parts, |
78 | | - ].flatten.join(INDEXABLE_CONTENT_SEPARATOR) |
79 | | - end |
80 | | - |
81 | | - private |
82 | | - |
83 | | - def link |
84 | | - document_hash[:base_path].presence || document_hash.dig(:details, :url) |
85 | | - end |
86 | | - |
87 | | - def link_relative? |
88 | | - link&.start_with?("/") |
89 | | - end |
90 | | - |
91 | | - def url |
92 | | - return link unless link_relative? |
93 | | - |
94 | | - Plek.website_root + link |
95 | | - end |
96 | | - |
97 | | - def additional_searchable_text |
98 | | - values = ADDITIONAL_SEARCHABLE_TEXT_VALUES_JSON_PATHS.map { _1.on(document_hash) } |
99 | | - values |
100 | | - .flatten |
101 | | - .compact_blank |
102 | | - .join(ADDITIONAL_SEARCHABLE_TEXT_VALUES_SEPARATOR) |
103 | | - end |
104 | | - |
105 | | - def public_timestamp |
106 | | - return nil unless document_hash[:public_updated_at] |
107 | | - |
108 | | - # rubocop:disable Rails/TimeZone (string already contains timezone info which would be lost) |
109 | | - Time.parse(document_hash[:public_updated_at]).to_i |
110 | | - # rubocop:enable Rails/TimeZone |
111 | | - end |
112 | | - |
113 | | - def historic? |
114 | | - political = document_hash.dig(:details, :political) || false |
115 | | - government = document_hash.dig(:expanded_links, :government)&.first |
116 | | - |
117 | | - political && government&.dig(:details, :current) == false |
118 | | - end |
119 | | - |
120 | | - def government_name |
121 | | - document_hash |
122 | | - .dig(:expanded_links, :government) |
123 | | - &.first |
124 | | - &.dig(:title) |
125 | | - end |
126 | | - |
127 | | - def organisation_state |
128 | | - document_hash |
129 | | - .dig(:details, :organisation_govuk_status, :status) |
130 | | - end |
131 | | - |
132 | | - def parts |
133 | | - document_hash |
134 | | - .dig(:details, :parts) |
135 | | - &.map do |
136 | | - { |
137 | | - slug: _1[:slug], |
138 | | - title: _1[:title], |
139 | | - body: ContentWithMultipleTypes.new(_1[:body]).summarized_text_content, |
140 | | - } |
141 | | - end |
142 | | - end |
143 | 10 | end |
144 | 11 | end |
0 commit comments