Class: XapianDb::Resultset

Inherits:
Array
  • Object
show all
Includes:
Utilities
Defined in:
lib/xapian_db/resultset.rb

Overview

The resultset encapsulates a Xapian::Query object and allows paged access to the found documents. The resultset is compatible with will_paginate and kaminari.

Examples:

Process the first page of a resultsest

resultset.paginate(:page => 1, :per_page => 10).each do |doc|
  # do something with the xapian document
end

Use the resultset and will_paginate in a view

<%= will_paginate resultset %>

Use the resultset and kaminari in a view

<%= paginate resultset %>

Author:

  • Gernot Kogler

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utilities

#assert_valid_keys, #camelize, #constantize

Constructor Details

#initialize(enquiry, options = {}) ⇒ Resultset

Constructor

Parameters:

Options Hash (options):

  • :db_size (Integer)

    The current size (nr of docs) of the database

  • :limit (Integer)

    The maximum number of documents to retrieve

  • :offset (Integer)

    The index of the first result to retrieve

  • :page (Integer) — default: 1

    The page number to retrieve

  • :per_page (Integer) — default: 10

    How many docs per page? Ignored if a limit option is given

  • :spelling_suggestion (String) — default: nil

    The spelling corrected query (if a language is configured)


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/xapian_db/resultset.rb', line 53

def initialize(enquiry, options={})

  return build_empty_resultset if enquiry.nil?
  params               = options.dup
  db_size              = params.delete :db_size
  @spelling_suggestion = params.delete :spelling_suggestion
  limit                = params.delete :limit
  offset               = params.delete :offset
  page                 = params.delete :page
  per_page             = params.delete :per_page
  raise ArgumentError.new "unsupported options for resultset: #{params}" if params.size > 0
  raise ArgumentError.new "db_size option is required" unless db_size

  unless (page.nil? && per_page.nil?) || (limit.nil? && offset.nil?)
    raise ArgumentError.new "Impossible combination of parameters. Either pass page and/or per_page, or limit and/or offset."
  end

  calculated_page = offset.nil? || limit.nil? ? nil : (offset.to_f / limit.to_f) + 1

  limit    = limit.nil? ? db_size : limit.to_i
  per_page = per_page.nil? ? limit.to_i : per_page.to_i
  page     = page.nil? ? (calculated_page.nil? ? 1 : calculated_page) : page.to_i
  offset   = offset.nil? ? (page - 1) * per_page : offset.to_i
  count    = per_page < limit ? per_page : limit

  return build_empty_resultset if (page - 1) * per_page > db_size
  result_window = enquiry.mset(offset, count)
  @hits = result_window.matches_estimated
  return build_empty_resultset if @hits == 0

  self.replace result_window.matches.map{|match| decorate(match).document}
  @total_pages  = (@hits / per_page.to_f).ceil
  @current_page = (page == page.to_i) ? page.to_i : page
  @limit_value  = per_page
end

Instance Attribute Details

#current_pageInteger (readonly)

The current page

Returns:

  • (Integer)

34
35
36
# File 'lib/xapian_db/resultset.rb', line 34

def current_page
  @current_page
end

#hitsInteger (readonly) Also known as: total_count, total_entries

The number of hits

Returns:

  • (Integer)

23
24
25
# File 'lib/xapian_db/resultset.rb', line 23

def hits
  @hits
end

#limit_valueObject (readonly)

The number of records per page


41
42
43
# File 'lib/xapian_db/resultset.rb', line 41

def limit_value
  @limit_value
end

#spelling_suggestionString

The spelling corrected query (if a language is configured)

Returns:

  • (String)

38
39
40
# File 'lib/xapian_db/resultset.rb', line 38

def spelling_suggestion
  @spelling_suggestion
end

#total_pagesInteger (readonly) Also known as: num_pages

The number of pages

Returns:

  • (Integer)

29
30
31
# File 'lib/xapian_db/resultset.rb', line 29

def total_pages
  @total_pages
end

Instance Method Details

#build_empty_resultsetObject

Build an empty resultset


102
103
104
105
106
107
108
# File 'lib/xapian_db/resultset.rb', line 102

def build_empty_resultset
  @hits         = 0
  @total_pages  = 0
  @current_page = 0
  @limit_value  = 0
  self
end

#decorate(match) ⇒ Xapian::Match

Decorate a Xapian match with field accessors for each configured attribute

Parameters:

  • a (Xapian::Match)

    match

Returns:

  • (Xapian::Match)

    the decorated match


113
114
115
116
117
118
119
# File 'lib/xapian_db/resultset.rb', line 113

def decorate(match)
  klass_name = match.document.values[0].value
  blueprint  = XapianDb::DocumentBlueprint.blueprint_for klass_name
  match.document.extend blueprint.accessors_module
  match.document.instance_variable_set :@score, match.percent
  match
end

#next_pageInteger

The next page number

Returns:

  • (Integer)

    The number of the next page or nil, if we are at the last page


97
98
99
# File 'lib/xapian_db/resultset.rb', line 97

def next_page
  @current_page < @total_pages ? (@current_page + 1): nil
end

#previous_pageInteger

The previous page number

Returns:

  • (Integer)

    The number of the previous page or nil, if we are at page 1


91
92
93
# File 'lib/xapian_db/resultset.rb', line 91

def previous_page
  @current_page > 1 ? (@current_page - 1) : nil
end