xapian_db 1.3.5.4 → 1.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/README.rdoc +32 -2
- data/lib/xapian_db.rb +4 -5
- data/lib/xapian_db/adapters/active_record_adapter.rb +7 -6
- data/lib/xapian_db/config.rb +17 -1
- data/lib/xapian_db/database.rb +17 -2
- data/lib/xapian_db/document_blueprint.rb +60 -10
- data/lib/xapian_db/index_writers/beanstalk_worker.rb +2 -3
- data/lib/xapian_db/index_writers/beanstalk_writer.rb +2 -2
- data/lib/xapian_db/index_writers/direct_writer.rb +6 -6
- data/lib/xapian_db/index_writers/no_op_writer.rb +2 -2
- data/lib/xapian_db/index_writers/resque_worker.rb +1 -2
- data/lib/xapian_db/index_writers/resque_writer.rb +2 -3
- data/lib/xapian_db/index_writers/sidekiq_worker.rb +1 -1
- data/lib/xapian_db/index_writers/sidekiq_writer.rb +2 -3
- data/lib/xapian_db/index_writers/transactional_writer.rb +2 -4
- data/lib/xapian_db/indexer.rb +1 -0
- data/lib/xapian_db/resultset.rb +14 -6
- metadata +21 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8fcb96848f64b5fb55dee7fcd4cd2fa246c3161b
|
4
|
+
data.tar.gz: d084663854eccb8578c0cc6f8c91244034a51f37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9887f97d274399336ff92f7ee41d9b6d9a89df483a355b28673891bd4c96acc8541548e5dc95e2cd15e90739fc72480d6bbedf1dad96de488f0a4cc12424ac44
|
7
|
+
data.tar.gz: 86a87a39b867e19bf1ba8115b94657ea924628c0a62c670bd4cc68069b590196c7414dd471e1b76937ebf4debc463c7361b67af6b1adb99bd64a8edf95dd4fb7
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
##1.3.7 (January 12th, 2016)
|
2
|
+
|
3
|
+
Breaking Changes:
|
4
|
+
|
5
|
+
- search methods accept either a limit option OR page / per_page options, not both
|
6
|
+
|
7
|
+
Fixes:
|
8
|
+
|
9
|
+
- `XapianDb.database.delete_docs_of_class(klass)` now deletes docs of all descendants of `klass`, too (if tracked)
|
10
|
+
|
11
|
+
Changes:
|
12
|
+
|
13
|
+
- Ability to declare dependenices between blueprints
|
14
|
+
- Support for result ordering
|
15
|
+
- added a indexer preprocess callback to manipulate the terms that the indexer will index
|
16
|
+
|
17
|
+
##1.3.6 (August 14th, 2015)
|
18
|
+
|
19
|
+
Changes:
|
20
|
+
|
21
|
+
- The required Ruby version is now 2.0.0 since we started using keyword parameters in method definitions
|
22
|
+
- Ability do define and handle dependencies between blueprints (see README)
|
23
|
+
- explicit order option for searches
|
24
|
+
|
1
25
|
##1.3.5.4 (Jan 13th, 2015)
|
2
26
|
|
3
27
|
Fixes:
|
data/README.rdoc
CHANGED
@@ -32,9 +32,9 @@ I tried hard but I couldn't find such a thing so I decided to write it, based on
|
|
32
32
|
|
33
33
|
== Requirements
|
34
34
|
|
35
|
-
* ruby
|
35
|
+
* ruby 2.0.0 or newer
|
36
36
|
* rails 3.0 or newer (if you want to use it with rails)
|
37
|
-
* xapian-core and xapian-ruby binaries installed
|
37
|
+
* xapian-core and xapian-ruby binaries 1.2.x installed
|
38
38
|
|
39
39
|
== Installing xapian binaries
|
40
40
|
|
@@ -194,6 +194,32 @@ are ordered by relevance and - within the same relevance - by the natural sort o
|
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
197
|
+
You can specify a Ruby method for preprocessing the indexed terms. The method needs to be a class method that takes one argument (the terms to be indexed) and
|
198
|
+
returns a string. You can configure it globaly in the config or on a blueprint. For example, this setup will make words with accented e characters searchable
|
199
|
+
by their accentless form:
|
200
|
+
|
201
|
+
class Util
|
202
|
+
def self.strip_accents(terms)
|
203
|
+
terms.gsub(/[éèêëÉÈÊË]/, "e")
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
XapianDb::Config.setup do |config|
|
208
|
+
config.indexer_preprocess_callback UtilT.method(:strip_accents)
|
209
|
+
end
|
210
|
+
|
211
|
+
You may use attributes from associated objects in a blueprint; if you do that and an associated object is updated, your objects should be reindexed, too. You can tell XapnaDB about those dependencies like so:
|
212
|
+
|
213
|
+
XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
|
214
|
+
blueprint.attribue :address, :as => :json
|
215
|
+
|
216
|
+
blueprint.dependency :Address, when_changed: %i(street zip city) do |address|
|
217
|
+
Person.joins{ address }.where{ adresses.id == my{ address.id } }
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
The block you supply to the dependency declaration must return a collection of objects that should get reindexed, too.
|
222
|
+
|
197
223
|
If you want to manage the (re)indexing of your objects on your own, turn off autoindexing in your blueprint:
|
198
224
|
|
199
225
|
XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
|
@@ -246,6 +272,10 @@ You can query attributes:
|
|
246
272
|
|
247
273
|
results = XapianDb.search "name:Foo"
|
248
274
|
|
275
|
+
You can force the sort order:
|
276
|
+
|
277
|
+
results = XapianDb.search "name:Foo", order: [:name]
|
278
|
+
|
249
279
|
You can query objects of a specific class:
|
250
280
|
|
251
281
|
results = Person.search "name:Foo"
|
data/lib/xapian_db.rb
CHANGED
@@ -105,9 +105,9 @@ module XapianDb
|
|
105
105
|
|
106
106
|
# Update an object in the index
|
107
107
|
# @param [Object] obj An instance of a class with a blueprint configuration
|
108
|
-
def self.index(obj, commit=true)
|
108
|
+
def self.index(obj, commit=true, changed_attrs: [])
|
109
109
|
writer = @block_writer || XapianDb::Config.writer
|
110
|
-
writer.index obj, commit
|
110
|
+
writer.index obj, commit, changed_attrs: changed_attrs
|
111
111
|
end
|
112
112
|
|
113
113
|
# Remove a document from the index
|
@@ -119,11 +119,11 @@ module XapianDb
|
|
119
119
|
|
120
120
|
# Update or delete a xapian document belonging to an object depending on the ignore_if logic(if present)
|
121
121
|
# @param [Object] object An instance of a class with a blueprint configuration
|
122
|
-
def self.reindex(object, commit=true)
|
122
|
+
def self.reindex(object, commit=true, changed_attrs: [])
|
123
123
|
writer = @block_writer || XapianDb::Config.writer
|
124
124
|
blueprint = XapianDb::DocumentBlueprint.blueprint_for object.class.name
|
125
125
|
if blueprint.should_index?(object)
|
126
|
-
writer.index object, commit
|
126
|
+
writer.index object, commit, changed_attrs: changed_attrs
|
127
127
|
else
|
128
128
|
writer.delete_doc_with object.xapian_id, commit
|
129
129
|
end
|
@@ -191,5 +191,4 @@ module XapianDb
|
|
191
191
|
@block_writer = nil
|
192
192
|
end
|
193
193
|
end
|
194
|
-
|
195
194
|
end
|
@@ -49,7 +49,12 @@ module XapianDb
|
|
49
49
|
# add the after commit logic, unless the blueprint has autoindexing turned off
|
50
50
|
if XapianDb::DocumentBlueprint.blueprint_for(klass.name).autoindex?
|
51
51
|
after_commit do
|
52
|
-
|
52
|
+
unless self.destroyed?
|
53
|
+
XapianDb.reindex(self, true, changed_attrs: self.previous_changes.keys)
|
54
|
+
XapianDb::DocumentBlueprint.dependencies_for(klass.name, self.previous_changes.keys).each do |dependency|
|
55
|
+
dependency.block.call(self).each{ |model| XapianDb.reindex model, true, changed_attrs: self.previous_changes.keys }
|
56
|
+
end
|
57
|
+
end
|
53
58
|
end
|
54
59
|
end
|
55
60
|
|
@@ -64,7 +69,6 @@ module XapianDb
|
|
64
69
|
XapianDb.reindex_class(klass, options)
|
65
70
|
end
|
66
71
|
end
|
67
|
-
|
68
72
|
end
|
69
73
|
|
70
74
|
# Implement the document helper methods on a module
|
@@ -76,7 +80,7 @@ module XapianDb
|
|
76
80
|
|
77
81
|
# Implement access to the model id
|
78
82
|
define_method :id do
|
79
|
-
return @id unless @
|
83
|
+
return @id unless @id.nil?
|
80
84
|
# retrieve the class and id from data
|
81
85
|
klass_name, id = data.split("-")
|
82
86
|
@id = id.to_i
|
@@ -90,11 +94,8 @@ module XapianDb
|
|
90
94
|
klass = constantize klass_name
|
91
95
|
@indexed_object = klass.find(id.to_i)
|
92
96
|
end
|
93
|
-
|
94
97
|
end
|
95
|
-
|
96
98
|
end
|
97
|
-
|
98
99
|
end
|
99
100
|
end
|
100
101
|
end
|
data/lib/xapian_db/config.rb
CHANGED
@@ -32,7 +32,7 @@ module XapianDb
|
|
32
32
|
end
|
33
33
|
|
34
34
|
# Install delegates for the config instance variables
|
35
|
-
[:database, :adapter, :writer, :stemmer, :stopper].each do |attr|
|
35
|
+
[:database, :adapter, :writer, :stemmer, :stopper, :preprocess_terms].each do |attr|
|
36
36
|
define_method attr do
|
37
37
|
@config.nil? ? nil : @config.instance_variable_get("@_#{attr}")
|
38
38
|
end
|
@@ -183,5 +183,21 @@ module XapianDb
|
|
183
183
|
@_enabled_query_flags.delete flag
|
184
184
|
end
|
185
185
|
|
186
|
+
# Set the indexer preprocess callback.
|
187
|
+
# @param [Method] method a class method; needs to take one parameter and return a string.
|
188
|
+
# @example
|
189
|
+
# class Util
|
190
|
+
# def self.strip_accents(terms)
|
191
|
+
# terms.gsub(/[éèêëÉÈÊË]/, "e")
|
192
|
+
# end
|
193
|
+
# end
|
194
|
+
#
|
195
|
+
# XapianDb::Config.setup do |config|
|
196
|
+
# config.indexer_preprocess_callback Util.method(:strip_accents)
|
197
|
+
# end
|
198
|
+
def indexer_preprocess_callback(method)
|
199
|
+
@_preprocess_terms = method
|
200
|
+
end
|
201
|
+
|
186
202
|
end
|
187
203
|
end
|
data/lib/xapian_db/database.rb
CHANGED
@@ -35,10 +35,19 @@ module XapianDb
|
|
35
35
|
true
|
36
36
|
end
|
37
37
|
|
38
|
-
# Delete all docs of a specific class
|
38
|
+
# Delete all docs of a specific class.
|
39
|
+
#
|
40
|
+
# If `klass` tracks its descendants, then docs of any subclasses will be deleted, too.
|
41
|
+
# (ActiveRecord does this by default; the gem 'descendants_tracker' offers an alternative.)
|
42
|
+
#
|
39
43
|
# @param [Class] klass A class that has a {XapianDb::DocumentBlueprint} configuration
|
40
44
|
def delete_docs_of_class(klass)
|
41
45
|
writer.delete_document("C#{klass}")
|
46
|
+
if klass.respond_to? :descendants
|
47
|
+
klass.descendants.each do |subclass|
|
48
|
+
writer.delete_document("C#{subclass}")
|
49
|
+
end
|
50
|
+
end
|
42
51
|
true
|
43
52
|
end
|
44
53
|
|
@@ -73,6 +82,12 @@ module XapianDb
|
|
73
82
|
enquiry.query = query
|
74
83
|
sort_indices = opts.delete :sort_indices
|
75
84
|
sort_decending = opts.delete :sort_decending
|
85
|
+
order = opts.delete :order
|
86
|
+
raise ArgumentError.new "you can't use sort_indices and order, only one of them" if sort_indices && order
|
87
|
+
|
88
|
+
if order
|
89
|
+
sort_indices = order.map{ |attr_name| XapianDb::DocumentBlueprint.value_number_for attr_name.to_sym }
|
90
|
+
end
|
76
91
|
|
77
92
|
sorter = Xapian::MultiValueKeyMaker.new
|
78
93
|
if sort_indices
|
@@ -80,7 +95,7 @@ module XapianDb
|
|
80
95
|
enquiry.set_sort_by_key_then_relevance(sorter, sort_decending)
|
81
96
|
else
|
82
97
|
sorter.add_value DocumentBlueprint.value_number_for(:natural_sort_order)
|
83
|
-
enquiry.set_sort_by_relevance_then_key sorter,
|
98
|
+
enquiry.set_sort_by_relevance_then_key sorter, false
|
84
99
|
end
|
85
100
|
|
86
101
|
opts[:spelling_suggestion] = @query_parser.spelling_suggestion
|
@@ -50,6 +50,7 @@ module XapianDb
|
|
50
50
|
# We can always do a field search on the name of the indexed class
|
51
51
|
@searchable_prefixes << "indexed_class"
|
52
52
|
@attributes = @blueprints.values.map { |blueprint| blueprint.attribute_names}.flatten.compact.uniq.sort || []
|
53
|
+
blueprint
|
53
54
|
end
|
54
55
|
|
55
56
|
# reset the blueprint setup
|
@@ -66,11 +67,17 @@ module XapianDb
|
|
66
67
|
# Get all configured classes
|
67
68
|
# @return [Array<Class>]
|
68
69
|
def configured_classes
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
70
|
+
if @blueprints
|
71
|
+
@blueprints.keys.map {|class_name| XapianDb::Utilities.constantize(class_name) }
|
72
|
+
else
|
73
|
+
[]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def dependencies_for(klass_name, changed_attrs)
|
78
|
+
@blueprints.values.map(&:dependencies)
|
79
|
+
.flatten
|
80
|
+
.select{ |dependency| dependency.dependent_on == klass_name && dependency.interested_in?(changed_attrs) }
|
74
81
|
end
|
75
82
|
|
76
83
|
# Get the blueprint for a class
|
@@ -167,7 +174,6 @@ module XapianDb
|
|
167
174
|
end
|
168
175
|
end
|
169
176
|
end
|
170
|
-
|
171
177
|
end
|
172
178
|
|
173
179
|
# ---------------------------------------------------------------------------------
|
@@ -258,15 +264,17 @@ module XapianDb
|
|
258
264
|
# Blueprint DSL methods
|
259
265
|
# ---------------------------------------------------------------------------------
|
260
266
|
|
261
|
-
attr_reader :lazy_base_query, :_natural_sort_order
|
267
|
+
attr_reader :lazy_base_query, :_natural_sort_order, :dependencies
|
262
268
|
|
263
269
|
# Construct the blueprint
|
264
270
|
def initialize
|
265
271
|
@attributes_hash = {}
|
266
272
|
@indexed_methods_hash = {}
|
267
273
|
@type_map = {}
|
274
|
+
@dependencies = []
|
268
275
|
@_natural_sort_order = :id
|
269
276
|
@autoindex = true
|
277
|
+
@indexer_preprocess_callback = nil
|
270
278
|
end
|
271
279
|
|
272
280
|
# Set the adapter
|
@@ -377,7 +385,7 @@ module XapianDb
|
|
377
385
|
@ignore_expression = block
|
378
386
|
end
|
379
387
|
|
380
|
-
# Define a base query to select one or all objects of the indexed class. The reason for a
|
388
|
+
# Define a base query to select one or all objects of the indexed class. The reason for a
|
381
389
|
# base query is to optimize the query avoiding th 1+n problematic. The base query should only
|
382
390
|
# include joins(...) and includes(...) calls.
|
383
391
|
# @param [expression] a base query expression
|
@@ -400,6 +408,33 @@ module XapianDb
|
|
400
408
|
@_natural_sort_order = name || block
|
401
409
|
end
|
402
410
|
|
411
|
+
def dependency(klass_name, when_changed: [], &block)
|
412
|
+
@dependencies << Dependency.new(klass_name.to_s, when_changed, block)
|
413
|
+
end
|
414
|
+
|
415
|
+
# Set the indexer preprocess callback.
|
416
|
+
# @param [Method] method a class method; needs to take one parameter and return a string.
|
417
|
+
# @example
|
418
|
+
# class Util
|
419
|
+
# def self.strip_accents(terms)
|
420
|
+
# terms.gsub(/[éèêëÉÈÊË]/, "e")
|
421
|
+
# end
|
422
|
+
# end
|
423
|
+
#
|
424
|
+
# XapianDb::DocumentBlueprint.setup(:IndexedObject) do |blueprint|
|
425
|
+
# blueprint.attribute :name
|
426
|
+
# blueprint.indexer_preprocess_callback Util.method(:strip_accents)
|
427
|
+
# end
|
428
|
+
def indexer_preprocess_callback(method)
|
429
|
+
@indexer_preprocess_callback = method
|
430
|
+
end
|
431
|
+
|
432
|
+
# Reader for indexer_preprocess_callback.
|
433
|
+
# Returns the terms preprocessing method for this blueprint, the global method from config or nil.
|
434
|
+
def preprocess_terms
|
435
|
+
@indexer_preprocess_callback || XapianDb::Config.preprocess_terms
|
436
|
+
end
|
437
|
+
|
403
438
|
# Options for an indexed method
|
404
439
|
class IndexOptions
|
405
440
|
|
@@ -414,7 +449,24 @@ module XapianDb
|
|
414
449
|
@no_split = options[:no_split]
|
415
450
|
@block = options[:block]
|
416
451
|
end
|
452
|
+
end
|
453
|
+
|
454
|
+
class Dependency
|
455
|
+
|
456
|
+
attr_reader :dependent_on, :trigger_attributes, :block
|
457
|
+
|
458
|
+
# Constructor
|
459
|
+
# @param [String] klass_name Name of the dependent class
|
460
|
+
# @param [Array] trigger_attributes List of attributes to watch for changes (if empty, triggers on any change)
|
461
|
+
# @option [Block] block Block that is called when changes are detected; the block must return an array of indexeable objects
|
462
|
+
def initialize(klass_name, trigger_attributes, block)
|
463
|
+
@dependent_on, @trigger_attributes, @block = klass_name, trigger_attributes.map(&:to_s), block
|
464
|
+
end
|
417
465
|
|
466
|
+
def interested_in?(changed_attrs)
|
467
|
+
return true if @trigger_attributes.empty?
|
468
|
+
(@trigger_attributes & changed_attrs).any?
|
469
|
+
end
|
418
470
|
end
|
419
471
|
|
420
472
|
private
|
@@ -431,7 +483,5 @@ module XapianDb
|
|
431
483
|
@reserved_method_names ||= Xapian::Document.instance_methods
|
432
484
|
@reserved_method_names.include?(attr_name.to_sym)
|
433
485
|
end
|
434
|
-
|
435
486
|
end
|
436
|
-
|
437
487
|
end
|
@@ -13,7 +13,7 @@ module XapianDb
|
|
13
13
|
def index_task(options)
|
14
14
|
klass = constantize options[:class]
|
15
15
|
obj = klass.respond_to?(:get) ? klass.get(options[:id]) : klass.find(options[:id])
|
16
|
-
DirectWriter.index obj
|
16
|
+
DirectWriter.index obj, true, changed_attrs: options[:changed_attrs]
|
17
17
|
end
|
18
18
|
|
19
19
|
def delete_doc_task(options)
|
@@ -24,7 +24,6 @@ module XapianDb
|
|
24
24
|
klass = constantize options[:class]
|
25
25
|
DirectWriter.reindex_class klass, :verbose => false
|
26
26
|
end
|
27
|
-
|
28
27
|
end
|
29
28
|
end
|
30
|
-
end
|
29
|
+
end
|
@@ -18,8 +18,8 @@ module XapianDb
|
|
18
18
|
|
19
19
|
# Update an object in the index
|
20
20
|
# @param [Object] obj An instance of a class with a blueprint configuration
|
21
|
-
def index(obj, commit=true)
|
22
|
-
beanstalk.put( {:task => "index_task", :class => obj.class.name, :id => obj.id }.to_json )
|
21
|
+
def index(obj, commit=true, changed_attrs: [])
|
22
|
+
beanstalk.put( { :task => "index_task", :class => obj.class.name, :id => obj.id, :changed_attrs => changed_attrs }.to_json )
|
23
23
|
end
|
24
24
|
|
25
25
|
# Remove an object from the index
|
@@ -17,11 +17,11 @@ module XapianDb
|
|
17
17
|
class << self
|
18
18
|
|
19
19
|
# Update an object in the index
|
20
|
-
# @param [Object]
|
21
|
-
def index(
|
22
|
-
blueprint = XapianDb::DocumentBlueprint.blueprint_for(
|
20
|
+
# @param [Object] object An instance of a class with a blueprint configuration
|
21
|
+
def index(object, commit=true, changed_attrs: [])
|
22
|
+
blueprint = XapianDb::DocumentBlueprint.blueprint_for(object.class.name)
|
23
23
|
indexer = XapianDb::Indexer.new(XapianDb.database, blueprint)
|
24
|
-
doc = indexer.build_document_for(
|
24
|
+
doc = indexer.build_document_for(object)
|
25
25
|
XapianDb.database.store_doc(doc)
|
26
26
|
XapianDb.database.commit if commit
|
27
27
|
end
|
@@ -35,10 +35,10 @@ module XapianDb
|
|
35
35
|
|
36
36
|
# Update or delete a xapian document belonging to an object depending on the ignore_if logic(if present)
|
37
37
|
# @param [Object] object An instance of a class with a blueprint configuration
|
38
|
-
def reindex(object, commit=true)
|
38
|
+
def reindex(object, commit=true, changed_attrs: [])
|
39
39
|
blueprint = XapianDb::DocumentBlueprint.blueprint_for object.class.name
|
40
40
|
if blueprint.should_index?(object)
|
41
|
-
index object, commit
|
41
|
+
index object, commit, changed_attrs: changed_attrs
|
42
42
|
else
|
43
43
|
delete_doc_with object.xapian_id, commit
|
44
44
|
end
|
@@ -12,7 +12,7 @@ module XapianDb
|
|
12
12
|
|
13
13
|
# Update an object in the index
|
14
14
|
# @param [Object] obj An instance of a class with a blueprint configuration
|
15
|
-
def index(obj, commit=true); end
|
15
|
+
def index(obj, commit=true, changed_attrs: []); end
|
16
16
|
|
17
17
|
# Remove an object from the index
|
18
18
|
# @param [String] xapian_id The document id
|
@@ -28,4 +28,4 @@ module XapianDb
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
31
|
-
end
|
31
|
+
end
|
@@ -22,7 +22,7 @@ module XapianDb
|
|
22
22
|
def index(options)
|
23
23
|
klass = constantize options['class']
|
24
24
|
obj = klass.respond_to?('get') ? klass.get(options['id']) : klass.find(options['id'])
|
25
|
-
DirectWriter.index obj
|
25
|
+
DirectWriter.index obj, true, changed_attrs: options[:changed_attrs]
|
26
26
|
end
|
27
27
|
|
28
28
|
def delete_doc(options)
|
@@ -34,7 +34,6 @@ module XapianDb
|
|
34
34
|
DirectWriter.reindex_class klass, :verbose => false
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
38
37
|
end
|
39
38
|
end
|
40
39
|
end
|
@@ -12,8 +12,8 @@ module XapianDb
|
|
12
12
|
|
13
13
|
# Update an object in the index
|
14
14
|
# @param [Object] obj An instance of a class with a blueprint configuration
|
15
|
-
def index(obj, commit=true)
|
16
|
-
Resque.enqueue worker_class, :index, :class => obj.class.name, :id => obj.id
|
15
|
+
def index(obj, commit=true, changed_attrs: [])
|
16
|
+
Resque.enqueue worker_class, :index, :class => obj.class.name, :id => obj.id, changed_attrs: changed_attrs
|
17
17
|
end
|
18
18
|
|
19
19
|
# Remove an object from the index
|
@@ -33,7 +33,6 @@ module XapianDb
|
|
33
33
|
end
|
34
34
|
private :worker_class
|
35
35
|
end
|
36
|
-
|
37
36
|
end
|
38
37
|
end
|
39
38
|
end
|
@@ -26,7 +26,7 @@ module XapianDb
|
|
26
26
|
def index(options)
|
27
27
|
klass = constantize options['class']
|
28
28
|
obj = klass.respond_to?('get') ? klass.get(options['id']) : klass.find(options['id'])
|
29
|
-
DirectWriter.index obj
|
29
|
+
DirectWriter.index obj, true, changed_attrs: options[:changed_attrs]
|
30
30
|
end
|
31
31
|
|
32
32
|
def delete_doc(options)
|
@@ -16,8 +16,8 @@ module XapianDb
|
|
16
16
|
|
17
17
|
# Update an object in the index
|
18
18
|
# @param [Object] obj An instance of a class with a blueprint configuration
|
19
|
-
def index(obj, commit=true)
|
20
|
-
Sidekiq::Client.enqueue worker_class, :index, :class => obj.class.name, :id => obj.id
|
19
|
+
def index(obj, commit=true, changed_attrs: [])
|
20
|
+
Sidekiq::Client.enqueue worker_class, :index, :class => obj.class.name, :id => obj.id, :changed_attrs => changed_attrs
|
21
21
|
end
|
22
22
|
|
23
23
|
# Remove an object from the index
|
@@ -37,7 +37,6 @@ module XapianDb
|
|
37
37
|
end
|
38
38
|
private :worker_class
|
39
39
|
end
|
40
|
-
|
41
40
|
end
|
42
41
|
end
|
43
42
|
end
|
@@ -20,7 +20,7 @@ module XapianDb
|
|
20
20
|
|
21
21
|
# Update an object in the index
|
22
22
|
# @param [Object] obj An instance of a class with a blueprint configuration
|
23
|
-
def index(obj, commit=false)
|
23
|
+
def index(obj, commit=false, changed_attrs: [])
|
24
24
|
@index_requests << obj
|
25
25
|
end
|
26
26
|
|
@@ -45,8 +45,6 @@ module XapianDb
|
|
45
45
|
@delete_requests.each { |xapian_id| writer.delete_doc_with xapian_id, false }
|
46
46
|
XapianDb.database.commit
|
47
47
|
end
|
48
|
-
|
49
48
|
end
|
50
|
-
|
51
49
|
end
|
52
|
-
end
|
50
|
+
end
|
data/lib/xapian_db/indexer.rb
CHANGED
@@ -86,6 +86,7 @@ module XapianDb
|
|
86
86
|
values = get_values_to_index_from obj
|
87
87
|
values.each do |value|
|
88
88
|
terms = value.to_s.downcase
|
89
|
+
terms = @blueprint.preprocess_terms.call(terms) if @blueprint.preprocess_terms
|
89
90
|
terms = split(terms) if XapianDb::Config.term_splitter_count > 0 && !options.no_split
|
90
91
|
# Add value with field name
|
91
92
|
term_generator.index_text(terms, options.weight, "X#{method.upcase}") if options.prefixed
|
data/lib/xapian_db/resultset.rb
CHANGED
@@ -46,6 +46,7 @@ module XapianDb
|
|
46
46
|
# @param [Hash] options
|
47
47
|
# @option options [Integer] :db_size The current size (nr of docs) of the database
|
48
48
|
# @option options [Integer] :limit The maximum number of documents to retrieve
|
49
|
+
# @option options [Integer] :offset The index of the first result to retrieve
|
49
50
|
# @option options [Integer] :page (1) The page number to retrieve
|
50
51
|
# @option options [Integer] :per_page (10) How many docs per page? Ignored if a limit option is given
|
51
52
|
# @option options [String] :spelling_suggestion (nil) The spelling corrected query (if a language is configured)
|
@@ -56,25 +57,32 @@ module XapianDb
|
|
56
57
|
db_size = params.delete :db_size
|
57
58
|
@spelling_suggestion = params.delete :spelling_suggestion
|
58
59
|
limit = params.delete :limit
|
60
|
+
offset = params.delete :offset
|
59
61
|
page = params.delete :page
|
60
62
|
per_page = params.delete :per_page
|
61
63
|
raise ArgumentError.new "unsupported options for resultset: #{params}" if params.size > 0
|
62
64
|
raise ArgumentError.new "db_size option is required" unless db_size
|
63
65
|
|
66
|
+
unless (page.nil? && per_page.nil?) || (limit.nil? && offset.nil?)
|
67
|
+
raise ArgumentError.new "Impossible combination of parameters. Either pass page and/or per_page, or limit and/or offset."
|
68
|
+
end
|
69
|
+
|
70
|
+
calculated_page = offset.nil? || limit.nil? ? nil : (offset.to_f / limit.to_f) + 1
|
71
|
+
|
64
72
|
limit = limit.nil? ? db_size : limit.to_i
|
65
|
-
per_page = per_page.nil? ? limit : per_page.to_i
|
66
|
-
page = page.nil? ? 1 : page.to_i
|
67
|
-
offset = (page - 1) * per_page
|
68
|
-
count
|
73
|
+
per_page = per_page.nil? ? limit.to_i : per_page.to_i
|
74
|
+
page = page.nil? ? (calculated_page.nil? ? 1 : calculated_page) : page.to_i
|
75
|
+
offset = offset.nil? ? (page - 1) * per_page : offset.to_i
|
76
|
+
count = per_page < limit ? per_page : limit
|
69
77
|
|
78
|
+
return build_empty_resultset if (page - 1) * per_page > db_size
|
70
79
|
result_window = enquiry.mset(offset, count)
|
71
80
|
@hits = result_window.matches_estimated
|
72
81
|
return build_empty_resultset if @hits == 0
|
73
|
-
raise ArgumentError.new "page #{@page} does not exist" if @hits > 0 && offset >= limit
|
74
82
|
|
75
83
|
self.replace result_window.matches.map{|match| decorate(match).document}
|
76
84
|
@total_pages = (@hits / per_page.to_f).ceil
|
77
|
-
@current_page = page
|
85
|
+
@current_page = (page == page.to_i) ? page.to_i : page
|
78
86
|
@limit_value = per_page
|
79
87
|
end
|
80
88
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xapian_db
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gernot Kogler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: daemons
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2.
|
47
|
+
version: 2.99.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 2.
|
54
|
+
version: 2.99.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: simplecov
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,14 +142,14 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - '='
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 1.2.
|
145
|
+
version: 1.2.22
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - '='
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 1.2.
|
152
|
+
version: 1.2.22
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: pry-rails
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,6 +164,20 @@ dependencies:
|
|
164
164
|
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: descendants_tracker
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
167
181
|
description: XapianDb is a ruby gem that combines features of nosql databases and
|
168
182
|
fulltext indexing. It is based on Xapian, an efficient and powerful indexing library
|
169
183
|
email: gernot.kogler (at) garaio (dot) com
|
@@ -239,7 +253,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
239
253
|
requirements:
|
240
254
|
- - ">="
|
241
255
|
- !ruby/object:Gem::Version
|
242
|
-
version:
|
256
|
+
version: 2.0.0
|
243
257
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
244
258
|
requirements:
|
245
259
|
- - ">="
|