Class: Ferret::Search::PhraseScorer

Inherits:
Scorer
  • Object
show all
Defined in:
lib/ferret/search/phrase_scorer.rb

Direct Known Subclasses

ExactPhraseScorer, SloppyPhraseScorer

Constant Summary

Constants inherited from Scorer

Scorer::MAX_DOCS

Instance Attribute Summary

Attributes inherited from Scorer

#similarity

Instance Method Summary collapse

Methods inherited from Scorer

#each_hit, #each_hit_up_to

Constructor Details

#initialize(weight, tps, positions, similarity, norms) ⇒ PhraseScorer

Returns a new instance of PhraseScorer.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/ferret/search/phrase_scorer.rb', line 6

def initialize(weight, tps, positions, similarity, norms) 
  super(similarity)
  @norms = norms
  @weight = weight
  @value = weight.value
  @first_time = true
  @more = true

  # convert tps to a list

  tps.length.times do |i|
    pp = PhrasePositions.new(tps[i], positions[i])
    if (@last != nil) # add next to end of list

      @last.next = pp
    else
      @first = pp
    end
    @last = pp
  end

  @pq = PhraseQueue.new(tps.length)  # construct empty pq

end

Instance Method Details

#do_nextObject

next without initial increment



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ferret/search/phrase_scorer.rb', line 43

def do_next()
  while (@more) 
    while (@more and @first.doc < @last.doc) # find doc w/ all the terms

      @more = @first.skip_to(@last.doc)      # skip first upto last

      first_to_last()                        # and move it to the end

    end

    if (@more) 
      # found a doc with all of the terms

      @freq = phrase_freq()                  # check for phrase

      if (@freq == 0.0)                      # no match

        @more = @last.next?                  # trigger further scanning

      else
        return true                          # found a match

      end
    end
  end
  return false                               # no more matches

end

#docObject



28
29
30
# File 'lib/ferret/search/phrase_scorer.rb', line 28

def doc()
  return @first.doc
end

#eachObject



63
64
65
66
67
68
69
# File 'lib/ferret/search/phrase_scorer.rb', line 63

def each()
  pp = @first
  while (pp != nil)
    yield pp
    pp = pp.next
  end
end

#explain(doc) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/ferret/search/phrase_scorer.rb', line 125

def explain(doc)
  tf_explanation = Explanation.new()

  while (next? and doc() < doc)
  end

  phrase_freq = (doc() == doc) ? @freq : 0.0
  tf_explanation.value = @similarity.tf(phrase_freq)
  tf_explanation.description = "tf(phrase_freq=#{phrase_freq})"

  return tf_explanation
end

#first_to_lastObject



118
119
120
121
122
123
# File 'lib/ferret/search/phrase_scorer.rb', line 118

def first_to_last() 
  @last.next = @first  # move first to end of list

  @last = @first
  @first = @first.next
  @last.next = nil
end

#initObject



87
88
89
90
91
92
93
94
# File 'lib/ferret/search/phrase_scorer.rb', line 87

def init()
  each do |pp|
    break if not @more = pp.next?
  end
  if @more
    sort()
  end
end

#next?Boolean

Returns:

  • (Boolean)


32
33
34
35
36
37
38
39
40
# File 'lib/ferret/search/phrase_scorer.rb', line 32

def next?
  if (@first_time) 
    init()
    @first_time = false
  elsif (@more) 
    @more = @last.next?                      # trigger further scanning

  end
  return do_next()
end

#phrase_freqObject

Raises:

  • (NotImplementedError)


83
84
85
# File 'lib/ferret/search/phrase_scorer.rb', line 83

def phrase_freq()
  raise NotImplementedError
end

#pq_to_listObject



104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/ferret/search/phrase_scorer.rb', line 104

def pq_to_list() 
  @last = @first = nil
  while (@pq.top() != nil) 
    pp = @pq.pop()
    if (@last != nil) # add next to end of list

      @last.next = pp
    else
      @first = pp
    end
    @last = pp
    pp.next = nil
  end
end

#scoreObject



71
72
73
74
75
# File 'lib/ferret/search/phrase_scorer.rb', line 71

def score()
  #puts("scoring #{@first.doc}")

  raw = similarity().tf(@freq) * @value      # raw score

  return raw * Similarity.decode_norm(@norms[@first.doc])  # normalize

end

#skip_to(target) ⇒ Object



77
78
79
80
81
# File 'lib/ferret/search/phrase_scorer.rb', line 77

def skip_to(target)
  each() { |pp| break if not @more = pp.skip_to(target) }
  sort() if @more                            # re-sort

  return do_next()
end

#sortObject



96
97
98
99
100
101
102
# File 'lib/ferret/search/phrase_scorer.rb', line 96

def sort() 
  @pq.clear()
  each() do |pp|
    @pq.push(pp)
  end
  pq_to_list()
end

#to_sObject



138
# File 'lib/ferret/search/phrase_scorer.rb', line 138

def to_s() return "phrase_scorer(#{@weight})" end