xapian_db 0.5.5 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +8 -0
- data/README.rdoc +9 -0
- data/lib/xapian_db/database.rb +2 -2
- data/lib/xapian_db/document_blueprint.rb +7 -1
- data/lib/xapian_db/query_parser.rb +1 -0
- data/lib/xapian_db/resultset.rb +26 -12
- metadata +2 -2
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
##0.5.6 (February 28th, 2011)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- documents returned by a query have the new score property that reflects the match relevance in percent (1-100%)
|
6
|
+
- added compatibility to the kaminari pagination gem (thanks, Javi)
|
7
|
+
- added support for phrase searches (XapianDb.search('"this exact sentence"'))
|
8
|
+
|
1
9
|
##0.5.5 (February 25th, 2011)
|
2
10
|
|
3
11
|
Fixes:
|
data/README.rdoc
CHANGED
@@ -155,6 +155,10 @@ You can query objects of a specific class:
|
|
155
155
|
|
156
156
|
results = Person.search "name:Foo"
|
157
157
|
|
158
|
+
You can search for exact phrases:
|
159
|
+
|
160
|
+
results = XapianDb.search('"this exact sentence"')
|
161
|
+
|
158
162
|
If you want to paginate the result, pass the :per_page argument:
|
159
163
|
|
160
164
|
results = Person.search "name:Foo", :per_page => 20
|
@@ -186,6 +190,7 @@ If you use a persistent database, the resultset may contain a spelling correctio
|
|
186
190
|
The results behave like an array:
|
187
191
|
|
188
192
|
doc = results.first
|
193
|
+
puts doc.score.to_s # Get the relevance of the document
|
189
194
|
puts doc.indexed_class # Get the type of the indexed object as a string, e.g. "Person"
|
190
195
|
puts doc.name # We can access the configured attributes
|
191
196
|
person = doc.indexed_object # Access the object behind this doc (lazy loaded)
|
@@ -194,6 +199,10 @@ Use a search result with will_paginate in a view:
|
|
194
199
|
|
195
200
|
<%= will_paginate @results %>
|
196
201
|
|
202
|
+
Or with kaminari:
|
203
|
+
|
204
|
+
<%= kaminari @results %>
|
205
|
+
|
197
206
|
=== Facets
|
198
207
|
|
199
208
|
If you want to implement a simple drilldown for your searches, you can use a global facets query:
|
data/lib/xapian_db/database.rb
CHANGED
@@ -43,7 +43,7 @@ module XapianDb
|
|
43
43
|
# Perform a search
|
44
44
|
# @param [String] expression A valid search expression.
|
45
45
|
# @param [Hash] options
|
46
|
-
# @option options [Integer] :per_page
|
46
|
+
# @option options [Integer] :per_page How many docs per page?
|
47
47
|
# @option options [Array<Integer>] :sort_indices (nil) An array of attribute indices to sort by. This
|
48
48
|
# option is used internally by the search method implemented on configured classes. Do not use it
|
49
49
|
# directly unless
|
@@ -58,7 +58,7 @@ module XapianDb
|
|
58
58
|
# resultset = db.search("name:foo")
|
59
59
|
# @return [XapianDb::Resultset] The resultset
|
60
60
|
def search(expression, options={})
|
61
|
-
opts = {:
|
61
|
+
opts = {:sort_decending => false}.merge(options)
|
62
62
|
@query_parser ||= QueryParser.new(self)
|
63
63
|
query = @query_parser.parse(expression)
|
64
64
|
|
@@ -142,11 +142,17 @@ module XapianDb
|
|
142
142
|
return @accessors_module unless @accessors_module.nil?
|
143
143
|
@accessors_module = Module.new
|
144
144
|
|
145
|
-
# Add the
|
145
|
+
# Add the accessors for the indexed class and the score
|
146
146
|
@accessors_module.instance_eval do
|
147
|
+
|
147
148
|
define_method :indexed_class do
|
148
149
|
self.values[0].value
|
149
150
|
end
|
151
|
+
|
152
|
+
define_method :score do
|
153
|
+
@score
|
154
|
+
end
|
155
|
+
|
150
156
|
end
|
151
157
|
|
152
158
|
# Add an accessor for each attribute
|
@@ -21,6 +21,7 @@ module XapianDb
|
|
21
21
|
@query_flags |= Xapian::QueryParser::FLAG_BOOLEAN # enable boolean operators
|
22
22
|
@query_flags |= Xapian::QueryParser::FLAG_BOOLEAN_ANY_CASE # enable case insensitive boolean operators
|
23
23
|
@query_flags |= Xapian::QueryParser::FLAG_SPELLING_CORRECTION # enable spelling corrections
|
24
|
+
@query_flags |= Xapian::QueryParser::FLAG_PHRASE # enable phrase searches
|
24
25
|
end
|
25
26
|
|
26
27
|
# Parse an expression
|
data/lib/xapian_db/resultset.rb
CHANGED
@@ -4,23 +4,27 @@ module XapianDb
|
|
4
4
|
|
5
5
|
# The resultset encapsulates a Xapian::Query object and allows paged access
|
6
6
|
# to the found documents.
|
7
|
-
# The resultset is compatible with will_paginate.
|
7
|
+
# The resultset is compatible with will_paginate and kaminari.
|
8
8
|
# @example Process the first page of a resultsest
|
9
9
|
# resultset.paginate(:page => 1, :per_page => 10).each do |doc|
|
10
10
|
# # do something with the xapian document
|
11
11
|
# end
|
12
12
|
# @example Use the resultset and will_paginate in a view
|
13
13
|
# <%= will_paginate resultset %>
|
14
|
+
# @example Use the resultset and kaminari in a view
|
15
|
+
# <%= paginate resultset %>
|
14
16
|
# @author Gernot Kogler
|
15
17
|
class Resultset < Array
|
16
18
|
|
17
19
|
# The number of hits
|
18
20
|
# @return [Integer]
|
19
21
|
attr_reader :hits
|
22
|
+
alias_method :total_count, :hits
|
20
23
|
|
21
24
|
# The number of pages
|
22
25
|
# @return [Integer]
|
23
26
|
attr_reader :total_pages
|
27
|
+
alias_method :num_pages, :total_pages
|
24
28
|
|
25
29
|
# The current page
|
26
30
|
# @return [Integer]
|
@@ -30,6 +34,9 @@ module XapianDb
|
|
30
34
|
# @return [String]
|
31
35
|
attr_accessor :spelling_suggestion
|
32
36
|
|
37
|
+
# The number of records per page
|
38
|
+
attr_reader :limit_value
|
39
|
+
|
33
40
|
# Constructor
|
34
41
|
# @param [Xapian::Enquire] enquiry a Xapian query result (see http://xapian.org/docs/apidoc/html/classXapian_1_1Enquire.html).
|
35
42
|
# Pass nil to get an empty result set.
|
@@ -41,18 +48,20 @@ module XapianDb
|
|
41
48
|
# @option options [String] :spelling_suggestion (nil) The spelling corrected query (if a language is configured)
|
42
49
|
def initialize(enquiry, options={})
|
43
50
|
|
44
|
-
|
45
|
-
return build_empty_resultset if
|
46
|
-
|
51
|
+
enquiry = enquiry
|
52
|
+
return build_empty_resultset if enquiry.nil?
|
47
53
|
db_size = options.delete :db_size
|
54
|
+
@spelling_suggestion = options.delete :spelling_suggestion
|
55
|
+
@hits = enquiry.mset(0, db_size).matches_estimated
|
56
|
+
return build_empty_resultset if @hits == 0
|
57
|
+
|
48
58
|
limit = options.delete :limit
|
49
59
|
page = options.delete :page
|
50
60
|
per_page = options.delete :per_page
|
51
|
-
@spelling_suggestion = options.delete :spelling_suggestion
|
52
61
|
raise ArgumentError.new "unsupported options for resultset: #{options}" if options.size > 0
|
53
62
|
raise ArgumentError.new "db_size option is required" unless db_size
|
54
63
|
|
55
|
-
|
64
|
+
|
56
65
|
limit ||= @hits
|
57
66
|
per_page ||= limit
|
58
67
|
@total_pages = (limit / per_page.to_f).ceil
|
@@ -61,9 +70,10 @@ module XapianDb
|
|
61
70
|
count = offset + per_page < limit ? per_page : limit - offset
|
62
71
|
raise ArgumentError.new "page #{@page} does not exist" if @hits > 0 && offset >= limit
|
63
72
|
|
64
|
-
result_window =
|
65
|
-
self.replace result_window.matches.map{|match| decorate(match.document
|
73
|
+
result_window = enquiry.mset(offset, count)
|
74
|
+
self.replace result_window.matches.map{|match| decorate(match).document}
|
66
75
|
@current_page = page
|
76
|
+
@limit_value = per_page
|
67
77
|
end
|
68
78
|
|
69
79
|
# The previous page number
|
@@ -88,11 +98,15 @@ module XapianDb
|
|
88
98
|
self
|
89
99
|
end
|
90
100
|
|
91
|
-
# Decorate a Xapian
|
92
|
-
|
93
|
-
|
101
|
+
# Decorate a Xapian match with field accessors for each configured attribute
|
102
|
+
# @param [Xapian::Match] a match
|
103
|
+
# @return [Xapian::Match] the decorated match
|
104
|
+
def decorate(match)
|
105
|
+
klass_name = match.document.values[0].value
|
94
106
|
blueprint = XapianDb::DocumentBlueprint.blueprint_for(Kernel.const_get(klass_name))
|
95
|
-
document.extend blueprint.accessors_module
|
107
|
+
match.document.extend blueprint.accessors_module
|
108
|
+
match.document.instance_variable_set :@score, match.percent
|
109
|
+
match
|
96
110
|
end
|
97
111
|
|
98
112
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: xapian_db
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.5.
|
5
|
+
version: 0.5.6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Gernot Kogler
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-02-
|
13
|
+
date: 2011-02-28 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|