xapian_db 1.3.5.4 → 1.3.7
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.
- 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
|
- - ">="
|