Skip to content

Commit c207615

Browse files
authored
Merge pull request #207 from MITLibraries/tco-141-regexable-suggested-resources
Adds Suggested Resource detection based on regex patterns
2 parents 19c74be + 643ed50 commit c207615

20 files changed

+341
-25
lines changed

app/controllers/demo_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ def detections
2323
@detections[:lcsh] = Detector::Lcsh.new(@searchterm).detections
2424
@detections[:standard_identifiers] = Detector::StandardIdentifiers.new(@searchterm).detections
2525
@detections[:suggested_resources] = Detector::SuggestedResource.full_term_match(@searchterm)
26+
@detections[:suggested_resources_patterns] = Detector::SuggestedResourcePattern.new(@searchterm)
2627
end
2728
end

app/graphql/types/detectors_type.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,19 @@ def standard_identifiers
2525
end
2626
end
2727

28+
# Prefer Term based SuggestedResources over Pattern Based Suggested Resources
2829
def suggested_resources
29-
Detector::SuggestedResource.full_term_match(@object).map do |suggested_resource|
30+
traditional_suggested_resources.presence || pattern_based_suggested_resources
31+
end
32+
33+
def traditional_suggested_resources
34+
Detector::SuggestedResource.full_term_match(@object) do |suggested_resource|
35+
{ title: suggested_resource.title, url: suggested_resource.url }
36+
end
37+
end
38+
39+
def pattern_based_suggested_resources
40+
Detector::SuggestedResourcePattern.new(@object).detections do |suggested_resource|
3041
{ title: suggested_resource.title, url: suggested_resource.url }
3142
end
3243
end

app/models/detector/bulk_checker.rb

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class Detector
55
# singleton class to access it
66
# See also: `PatternChecker` for shared instance methods
77
module BulkChecker
8-
# This method is intended to be used for inspecting detections during development.
8+
# check_all_matches is intended to be used for inspecting detections during development.
99
# Assumptions include
1010
# - the Class including this module implements a `detections` method (either via `attr_reader` or as a method)
1111
# that is only populated for Terms in which it has made a detection
@@ -24,14 +24,19 @@ def check_all_matches(output: false)
2424
matches.push [t.phrase, d.detections]
2525
end
2626

27-
if Rails.env.development?
28-
Rails.logger.ap matches
29-
30-
Rails.logger.ap "Total Terms: #{Term.count}"
31-
Rails.logger.ap "Total Matches: #{count}"
32-
end
27+
log_summary(matches) if Rails.env.development?
3328

3429
matches if output
3530
end
31+
32+
# log_summary formats and logs information collected in check_all_matches
33+
#
34+
# @param matches [array]. matches should be an array of [phrase, detections]
35+
def log_summary(matches)
36+
Rails.logger.info(ap(matches))
37+
38+
Rails.logger.info "Total Terms : #{Term.count}"
39+
Rails.logger.info "Total Matches: #{matches.count}"
40+
end
3641
end
3742
end

app/models/detector/standard_identifiers.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ class Detector
66
class StandardIdentifiers
77
attr_reader :detections
88

9-
def self.table_name_prefix
10-
'detector_'
11-
end
12-
139
# shared instance methods
1410
include Detector::PatternChecker
1511

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# frozen_string_literal: true
2+
3+
class Detector
4+
# Detector::SuggestedResourcePattern handles detections for patterns stored in our SuggestedPattern model
5+
class SuggestedResourcePattern
6+
attr_reader :detections
7+
8+
# shared singleton methods
9+
extend Detector::BulkChecker
10+
11+
def initialize(phrase)
12+
@detections = {}
13+
check_patterns(phrase)
14+
end
15+
16+
# check_patterns loops through all stored patterns from SuggestedPattern model, checks to see if they produce
17+
# matches for the incoming `phrase`, and if so creates a Hash with useful data
18+
#
19+
# @note Not using shared PatternChecker as we want to include additional data in the returned object
20+
# @param phrase [String]. A string representation of a searchterm (not an actual Term object)
21+
# @return primarily intended to add matches to @detections
22+
def check_patterns(phrase)
23+
sps = []
24+
SuggestedPattern.find_each do |sp|
25+
next unless Regexp.new(sp.pattern).match(phrase)
26+
27+
sps << {
28+
shortcode: sp.shortcode,
29+
title: sp.title,
30+
url: sp.url
31+
}
32+
@detections = sps
33+
end
34+
end
35+
36+
# The record method will consult the set of regex-based detectors that are defined in
37+
# SuggestedPattern records. Any matches will be registered as Detection records.
38+
#
39+
# @note There are multiple patterns within SuggestedPattern records. Each check is capable of generating
40+
# a separate Detection record.
41+
#
42+
# @return nil
43+
def self.record(term)
44+
sp = Detector::SuggestedResourcePattern.new(term.phrase)
45+
46+
sp.detections.each do
47+
Detection.find_or_create_by(
48+
term:,
49+
detector: Detector.where(name: 'SuggestedResourcePattern').first,
50+
detector_version: ENV.fetch('DETECTOR_VERSION', 'unset')
51+
)
52+
end
53+
54+
nil
55+
end
56+
end
57+
end

app/models/metrics/algorithms.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
# suggested_resource_exact :integer
1818
# lcsh :integer
1919
# citation :integer
20+
# barcode :integer
2021
#
2122
module Metrics
2223
# Algorithms aggregates statistics for matches for all SearchEvents

app/models/suggested_pattern.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# frozen_string_literal: true
2+
3+
# == Schema Information
4+
#
5+
# Table name: suggested_patterns
6+
#
7+
# id :integer not null, primary key
8+
# title :string not null
9+
# url :string not null
10+
# pattern :string not null
11+
# shortcode :string not null
12+
# created_at :datetime not null
13+
# updated_at :datetime not null
14+
#
15+
class SuggestedPattern < ApplicationRecord
16+
validates :title, presence: true
17+
validates :url, presence: true
18+
validates :pattern, presence: true, uniqueness: true
19+
validates :shortcode, presence: true, uniqueness: true
20+
end

app/models/term.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def record_detections
5555
Detector::Journal.record(self)
5656
Detector::Lcsh.record(self)
5757
Detector::SuggestedResource.record(self)
58+
Detector::SuggestedResourcePattern.record(self)
5859

5960
nil
6061
end

app/views/demo/view.html.erb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,15 @@
108108
<% else %>
109109
<p>No suggested resoure found.</p>
110110
<% end %>
111+
112+
<h2>Suggested Resource (Patterns)</h2>
113+
<% if @detections[:suggested_resources_patterns].detections.present? %>
114+
<p>Suggested resoure patterns found.</p>
115+
<% @detections[:suggested_resources_patterns].detections.each do |sr| %>
116+
<h3><%= sr[:title] %></h3>
117+
<p>URL: <%= link_to(sr[:url], sr[:url]) %></p>
118+
<% end %>
119+
120+
<% else %>
121+
<p>No suggested resoure patterns found.</p>
122+
<% end %>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class AddSuggestedPatterns < ActiveRecord::Migration[7.2]
2+
def change
3+
create_table :suggested_patterns do |t|
4+
t.string :title, null: false
5+
t.string :url, null: false
6+
t.string :pattern, null: false
7+
t.string :shortcode, null: false
8+
9+
t.timestamps
10+
end
11+
12+
add_index :suggested_patterns, :pattern, unique: true
13+
add_index :suggested_patterns, :shortcode, unique: true
14+
end
15+
end

0 commit comments

Comments
 (0)