xapian_db 1.3.5.4 → 1.3.7.4
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 +5 -5
- data/CHANGELOG.md +252 -201
- data/README.rdoc +34 -4
- data/lib/type_codec.rb +3 -3
- 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 +62 -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/query_parser.rb +13 -3
- data/lib/xapian_db/resultset.rb +14 -6
- metadata +28 -14
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
|
|
@@ -47,7 +47,7 @@ Make sure version 1.2.6 or newer is installed.
|
|
47
47
|
If you want to use xapian_db in a Rails app, you need Rails 3 or newer.
|
48
48
|
|
49
49
|
For a first look, look at the examples in the examples folder. There's the simple ruby script basic.rb that shows the basic
|
50
|
-
usage of XapianDB without rails. In the basic_rails folder you'll find a very simple Rails app
|
50
|
+
usage of XapianDB without rails. In the basic_rails folder you'll find a very simple Rails app using XapianDb.
|
51
51
|
|
52
52
|
The following steps assume that you are using xapian_db within a Rails app.
|
53
53
|
|
@@ -64,7 +64,7 @@ You can override these defaults by placing a config file named 'xapian_db.yml' i
|
|
64
64
|
adapter: datamapper # Avaliable adapters: :active_record, :datamapper
|
65
65
|
language: de # Global language; can be overridden for specific blueprints
|
66
66
|
term_min_length: 2 # Ignore single character terms
|
67
|
-
|
67
|
+
enabled_query_flags: FLAG_PHRASE, FLAG_SPELLING_CORRECTION
|
68
68
|
|
69
69
|
development:
|
70
70
|
database: db/xapian_db/development
|
@@ -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 Util.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/type_codec.rb
CHANGED
@@ -146,7 +146,7 @@ module XapianDb
|
|
146
146
|
# @return [String] the encoded number
|
147
147
|
def self.encode(number)
|
148
148
|
case number.class.name
|
149
|
-
when "Fixnum", "Float", "Bignum"
|
149
|
+
when "Fixnum", "Float", "Bignum", "Integer"
|
150
150
|
Xapian::sortable_serialise number
|
151
151
|
when "BigDecimal"
|
152
152
|
Xapian::sortable_serialise number.to_f
|
@@ -160,7 +160,7 @@ module XapianDb
|
|
160
160
|
# @return [BigDecimal] the decoded number
|
161
161
|
def self.decode(encoded_number)
|
162
162
|
begin
|
163
|
-
BigDecimal
|
163
|
+
BigDecimal(Xapian::sortable_unserialise(encoded_number).to_s)
|
164
164
|
rescue TypeError
|
165
165
|
raise ArgumentError.new "#{encoded_number} cannot be unserialized"
|
166
166
|
end
|
@@ -175,7 +175,7 @@ module XapianDb
|
|
175
175
|
def self.encode(number)
|
176
176
|
return nil if number.nil?
|
177
177
|
case number.class.name
|
178
|
-
when "Fixnum"
|
178
|
+
when "Fixnum", "Integer"
|
179
179
|
Xapian::sortable_serialise number
|
180
180
|
else
|
181
181
|
raise ArgumentError.new "#{number} was expected to be an integer"
|
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
|
@@ -26,6 +26,8 @@ module XapianDb
|
|
26
26
|
# ---------------------------------------------------------------------------------
|
27
27
|
class << self
|
28
28
|
|
29
|
+
attr_reader :blueprints
|
30
|
+
|
29
31
|
# Configure the blueprint for a class.
|
30
32
|
# Available options:
|
31
33
|
# - adapter (see {#adapter} for details)
|
@@ -50,6 +52,7 @@ module XapianDb
|
|
50
52
|
# We can always do a field search on the name of the indexed class
|
51
53
|
@searchable_prefixes << "indexed_class"
|
52
54
|
@attributes = @blueprints.values.map { |blueprint| blueprint.attribute_names}.flatten.compact.uniq.sort || []
|
55
|
+
blueprint
|
53
56
|
end
|
54
57
|
|
55
58
|
# reset the blueprint setup
|
@@ -66,11 +69,17 @@ module XapianDb
|
|
66
69
|
# Get all configured classes
|
67
70
|
# @return [Array<Class>]
|
68
71
|
def configured_classes
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
72
|
+
if @blueprints
|
73
|
+
@blueprints.keys.map {|class_name| XapianDb::Utilities.constantize(class_name) }
|
74
|
+
else
|
75
|
+
[]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def dependencies_for(klass_name, changed_attrs)
|
80
|
+
@blueprints.values.map(&:dependencies)
|
81
|
+
.flatten
|
82
|
+
.select{ |dependency| dependency.dependent_on == klass_name && dependency.interested_in?(changed_attrs) }
|
74
83
|
end
|
75
84
|
|
76
85
|
# Get the blueprint for a class
|
@@ -167,7 +176,6 @@ module XapianDb
|
|
167
176
|
end
|
168
177
|
end
|
169
178
|
end
|
170
|
-
|
171
179
|
end
|
172
180
|
|
173
181
|
# ---------------------------------------------------------------------------------
|
@@ -258,15 +266,17 @@ module XapianDb
|
|
258
266
|
# Blueprint DSL methods
|
259
267
|
# ---------------------------------------------------------------------------------
|
260
268
|
|
261
|
-
attr_reader :lazy_base_query, :_natural_sort_order
|
269
|
+
attr_reader :lazy_base_query, :_natural_sort_order, :dependencies
|
262
270
|
|
263
271
|
# Construct the blueprint
|
264
272
|
def initialize
|
265
273
|
@attributes_hash = {}
|
266
274
|
@indexed_methods_hash = {}
|
267
275
|
@type_map = {}
|
276
|
+
@dependencies = []
|
268
277
|
@_natural_sort_order = :id
|
269
278
|
@autoindex = true
|
279
|
+
@indexer_preprocess_callback = nil
|
270
280
|
end
|
271
281
|
|
272
282
|
# Set the adapter
|
@@ -377,7 +387,7 @@ module XapianDb
|
|
377
387
|
@ignore_expression = block
|
378
388
|
end
|
379
389
|
|
380
|
-
# Define a base query to select one or all objects of the indexed class. The reason for a
|
390
|
+
# Define a base query to select one or all objects of the indexed class. The reason for a
|
381
391
|
# base query is to optimize the query avoiding th 1+n problematic. The base query should only
|
382
392
|
# include joins(...) and includes(...) calls.
|
383
393
|
# @param [expression] a base query expression
|
@@ -400,6 +410,33 @@ module XapianDb
|
|
400
410
|
@_natural_sort_order = name || block
|
401
411
|
end
|
402
412
|
|
413
|
+
def dependency(klass_name, when_changed: [], &block)
|
414
|
+
@dependencies << Dependency.new(klass_name.to_s, when_changed, block)
|
415
|
+
end
|
416
|
+
|
417
|
+
# Set the indexer preprocess callback.
|
418
|
+
# @param [Method] method a class method; needs to take one parameter and return a string.
|
419
|
+
# @example
|
420
|
+
# class Util
|
421
|
+
# def self.strip_accents(terms)
|
422
|
+
# terms.gsub(/[éèêëÉÈÊË]/, "e")
|
423
|
+
# end
|
424
|
+
# end
|
425
|
+
#
|
426
|
+
# XapianDb::DocumentBlueprint.setup(:IndexedObject) do |blueprint|
|
427
|
+
# blueprint.attribute :name
|
428
|
+
# blueprint.indexer_preprocess_callback Util.method(:strip_accents)
|
429
|
+
# end
|
430
|
+
def indexer_preprocess_callback(method)
|
431
|
+
@indexer_preprocess_callback = method
|
432
|
+
end
|
433
|
+
|
434
|
+
# Reader for indexer_preprocess_callback.
|
435
|
+
# Returns the terms preprocessing method for this blueprint, the global method from config or nil.
|
436
|
+
def preprocess_terms
|
437
|
+
@indexer_preprocess_callback || XapianDb::Config.preprocess_terms
|
438
|
+
end
|
439
|
+
|
403
440
|
# Options for an indexed method
|
404
441
|
class IndexOptions
|
405
442
|
|
@@ -414,7 +451,24 @@ module XapianDb
|
|
414
451
|
@no_split = options[:no_split]
|
415
452
|
@block = options[:block]
|
416
453
|
end
|
454
|
+
end
|
455
|
+
|
456
|
+
class Dependency
|
457
|
+
|
458
|
+
attr_reader :dependent_on, :trigger_attributes, :block
|
417
459
|
|
460
|
+
# Constructor
|
461
|
+
# @param [String] klass_name Name of the dependent class
|
462
|
+
# @param [Array] trigger_attributes List of attributes to watch for changes (if empty, triggers on any change)
|
463
|
+
# @option [Block] block Block that is called when changes are detected; the block must return an array of indexeable objects
|
464
|
+
def initialize(klass_name, trigger_attributes, block)
|
465
|
+
@dependent_on, @trigger_attributes, @block = klass_name, trigger_attributes.map(&:to_s), block
|
466
|
+
end
|
467
|
+
|
468
|
+
def interested_in?(changed_attrs)
|
469
|
+
return true if @trigger_attributes.empty?
|
470
|
+
(@trigger_attributes & changed_attrs).any?
|
471
|
+
end
|
418
472
|
end
|
419
473
|
|
420
474
|
private
|
@@ -431,7 +485,5 @@ module XapianDb
|
|
431
485
|
@reserved_method_names ||= Xapian::Document.instance_methods
|
432
486
|
@reserved_method_names.include?(attr_name.to_sym)
|
433
487
|
end
|
434
|
-
|
435
488
|
end
|
436
|
-
|
437
489
|
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
|