Skip to content
This repository has been archived by the owner on May 25, 2022. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
… potential matches by relevance.

This fix adds;
1. An interface for the administrator to define a score threshold below which solr results will be rejected.
2. Removes potential matches that the user has not interacted with (confirmed/marked as invalid) and recreates them
 when a solr match is done.
3. Changed the potential matches search to return a hash of the model identifiers with their scores.
4. Returning potential match objects instead of children from Enquiry#potential_matches, in order to show the score
5. Displays the score along with the child in the summary panel of the enquiry's matches.
  • Loading branch information
ctumwebaze committed Sep 25, 2014
1 parent 0e8656d commit bf88b73
Show file tree
Hide file tree
Showing 30 changed files with 518 additions and 121 deletions.
100 changes: 54 additions & 46 deletions app/assets/stylesheets/new/_entity_summary.scss
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
.entity_list {
@extend .clearfix;


.entity_summary_panel {
background: $bg-child-summary;
border: 1px solid $border-child-summary;
@include borderRadius(2px);
margin: 10px 0px;
float:left;
float: left;
width: 100%;
@extend .clearfix;

p.checkbox{
p.checkbox {
background: #EEE;
border: 1px solid #D4D1D1;
border-right:0px;
border-right: 0px;
left: -231px;
padding: 5px;
position: absolute;
Expand All @@ -26,16 +25,16 @@
width: 160px;
height: 160px;

margin:10px;
margin: 10px;
background: #fff;
border: 10px solid #fff;
}

.photos, .audio{
.photos, .audio {
margin-right: 220px;
}

.photos .thumbnail{
.photos .thumbnail {
float: left;
margin: 2px;
height: 140px;
Expand All @@ -44,93 +43,102 @@
.summary_panel {
float: left;
padding: 10px 10px 10px 0px;
width:auto;
width: auto;
max-width: 78%;
min-width: 70%;
position: relative;

h2 {
font-size: 1.4em;

padding:5px 10px 10px 0px;
padding: 5px 10px 10px 0px;
}

.flag{
position:absolute;
top:0px;
width:22px;
height:36px;
.flag {
position: absolute;
top: 0px;
width: 22px;
height: 36px;
}

.reunited{
right:10px;
background:image-url('new/icon_reunited.png') no-repeat;
.reunited {
right: 10px;
background: image-url('new/icon_reunited.png') no-repeat;
}

.suspect{
.suspect {
right: 40px;
background:image-url('new/icon_flagged.png') no-repeat;
background: image-url('new/icon_flagged.png') no-repeat;
}

.photowall {
right: 70px;
background: image-url('new/icon_photowall.png') no-repeat;
}

.summary_item{
.summary_item {
@extend .clearfix;
border-top: 1px solid #ddd;
font-size: 0.95em;

.key {
color: #666;
padding:10px 0px 10px 20px;
float: left;
width:180px;
}
.value {
color: #000;
padding:10px;
float:left;
/*width:470px;*/
.key {
color: #666;
padding: 10px 0px 10px 20px;
float: left;
width: 180px;
}
.value {
color: #000;
padding: 10px;
float: left;
/*width:470px;*/

}
}
}

}

.action_panel {
background: #e8e8e8;
padding: 5px 10px 8px;
border-top: 1px solid $border-child-summary;
font-size: 1.3em;
color:#aaa;
color: #aaa;

a{
margin:0px 10px;
font-size: 0.8em;
}
a {
margin: 0px 10px;
font-size: 0.8em;
}

li{
li {
display: inline;
}

}

.left_side {
float: left;
}

.score_panel h2 {
text-align: center;
width: 100%;
font-size: 2em !important;
}
}

.results-count{
.results-count {
float: right;
margin: 0 26px 0 0;
color: #4b515f;
}

.child_summary_panel.sel{
background:#e5efff;
border:1px solid #bdd7ff;
.child_summary_panel.sel {
background: #e5efff;
border: 1px solid #bdd7ff;

p.checkbox{
background:#e5efff;
border:1px solid #bdd7ff;
p.checkbox {
background: #e5efff;
border: 1px solid #bdd7ff;
border-right: 0px;
}
}
Expand Down
22 changes: 22 additions & 0 deletions app/controllers/system_variables_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class SystemVariablesController < ApplicationController
def index
authorize! :read, SystemUsers
@system_variables = SystemVariable.all.all
end

def update
authorize! :update, SystemUsers
params[:system_variables].keys.each do |id|
variable = SystemVariable.find(id)
old_value = variable.value
variable.value = params[:system_variables][id]
variable.save!

if variable.name == SystemVariable::SCORE_THRESHOLD && variable.value != old_value
Enquiry.update_all_child_matches
end
end

redirect_to system_variables_path
end
end
4 changes: 2 additions & 2 deletions app/models/child.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ def find_matching_enquiries
previous_matches = potential_matches
criteria = Child.build_text_fields_for_solar.map { |field_name| self[field_name] unless self[field_name].nil? }
criteria.reject! { |c| c.nil? || c.empty? }
enquiries = MatchService.search_for_matching_enquiries(criteria)
PotentialMatch.create_matches_for_child id, enquiries.map(&:id)
hits = MatchService.search_for_matching_enquiries(criteria)
PotentialMatch.create_matches_for_child id, hits

unless previous_matches.eql?(potential_matches)
self.match_updated_at = Clock.now.to_s
Expand Down
46 changes: 35 additions & 11 deletions app/models/enquiry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,8 @@ def self.update_solr_indices

def potential_matches
potential_matches = PotentialMatch.by_enquiry_id.key(id).all
potential_matches.reject! { |pm| pm.marked_invalid? || pm.confirmed? }
child_ids = potential_matches.each.map(&:child_id)
child_ids.map { |id| Child.get(id) }
potential_matches.reject! { |pm| pm.marked_invalid? || pm.confirmed? || pm.deleted? }
potential_matches.sort_by(&:score).reverse! || []
end

def update_from(properties)
Expand All @@ -124,10 +123,19 @@ def update_from(properties)

def find_matching_children
previous_matches = potential_matches
children = MatchService.search_for_matching_children(criteria)
PotentialMatch.create_matches_for_enquiry id, children.map(&:id)
verify_format_of(previous_matches)
hits = MatchService.search_for_matching_children(criteria)
score_threshold = SystemVariable.find_by_name(SystemVariable::SCORE_THRESHOLD)

potential_matches_to_mark_deleted = previous_matches.select { |pm| hits[pm.child_id].to_f < score_threshold.value.to_f }
marked_potential_matches_as_deleted(potential_matches_to_mark_deleted)

potential_matches.reject! { |pm| potential_matches_to_mark_deleted.include?(pm) }
updated_potential_matches_score(potential_matches, hits)

hits.reject! { |_id, score| score.to_f < score_threshold.value.to_f }

PotentialMatch.create_matches_for_enquiry id, hits
verify_format_of(previous_matches)
unless previous_matches.eql?(potential_matches)
self.match_updated_at = Clock.now.to_s
end
Expand Down Expand Up @@ -172,6 +180,22 @@ def self.matchable_fields

private

def updated_potential_matches_score(matches, hits)
matches.each do |pm|
if hits.keys.include?(pm.child_id)
pm.score = hits[pm.child_id]
pm.save!
end
end
end

def marked_potential_matches_as_deleted(matches)
matches.each do |pm|
pm.deleted = true
pm.save!
end
end

def strip_whitespaces
keys.each do |key|
value = self[key]
Expand Down Expand Up @@ -200,11 +224,11 @@ def with_child_potential_matches(options = {})
PotentialMatch.paginates_per options.delete(:per_page)
page = options.delete(:page)
results = PotentialMatch.
all_valid_enquiry_ids(options).
page(page).
reduce.
group.
rows
all_valid_enquiry_ids(options).
page(page).
reduce.
group.
rows
pager.replace(results.map { |r| Enquiry.find(r['key']) })
pager.total_entries = PotentialMatch.all_valid_enquiry_ids.reduce.group.rows.count
end
Expand Down
8 changes: 6 additions & 2 deletions app/models/match_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ def self.search_for_matching_enquiries(criteria)
search = Sunspot.search(Enquiry) do
fulltext criteria.join(' '), :fields => Enquiry.matchable_fields.map(&:name), :minimum_match => 1
end
return search.results
results = {}
search.hits.each { |hit| results[hit.result.id] = hit.score }
return results
end
end

Expand All @@ -17,7 +19,9 @@ def self.search_for_matching_children(criteria)
search = Sunspot.search(Child) do
fulltext criteria.values.join(' '), :minimum_match => 1
end
return search.results
results = {}
search.hits.each { |hit| results[hit.result.id] = hit.score }
return results
end
end
end
16 changes: 10 additions & 6 deletions app/models/potential_match.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ class PotentialMatch < CouchRest::Model::Base
belongs_to :child
property :marked_invalid, TrueClass, :default => false
property :confirmed, TrueClass, :default => false
property :score, String
property :deleted, TrueClass, :default => false
timestamps!
validates :child_id, :uniqueness => {:scope => :enquiry_id}

design do
view :by_enquiry_id
view :by_enquiry_id_and_child_id
view :by_enquiry_id_and_confirmed
view :by_enquiry_id_and_marked_invalid
view :by_enquiry_id_and_deleted
view :by_child_id_and_confirmed
view :all_valid_enquiry_ids,
:map => "function(doc) {
Expand All @@ -29,16 +33,16 @@ def mark_as_invalid
end

class << self
def create_matches_for_child(child_id, enquiry_ids)
enquiry_ids.each do |id|
pm = PotentialMatch.new :enquiry_id => id, :child_id => child_id
def create_matches_for_child(child_id, hits)
hits.each do |enquiry_id, score|
pm = PotentialMatch.new :enquiry_id => enquiry_id, :child_id => child_id, :score => score
pm.save
end
end

def create_matches_for_enquiry(enquiry_id, child_ids)
child_ids.each do |id|
pm = PotentialMatch.new :enquiry_id => enquiry_id, :child_id => id
def create_matches_for_enquiry(enquiry_id, hits)
hits.each do |child_id, score|
pm = PotentialMatch.new :enquiry_id => enquiry_id, :child_id => child_id, :score => score
pm.save
end
end
Expand Down
15 changes: 15 additions & 0 deletions app/models/system_variable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class SystemVariable < CouchRest::Model::Base
use_database :system_setting

property :name, String
property :value, String

validates :name, :presence => true, :uniqueness => true
validates :value, :presence => true

design do
view :by_name
end

SCORE_THRESHOLD = 'SCORE_THRESHOLD'
end
4 changes: 4 additions & 0 deletions app/views/admin/index.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ h1
br
p
= link_to t("admin.highlight_fields"), highlight_fields_path
- if can? :manage, SystemUsers
br
p
= link_to t("admin.system_variables"), system_variables_path
- if can? :manage, SystemUsers
br
p
Expand Down
Loading

0 comments on commit bf88b73

Please sign in to comment.