oedipus 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +63 -9
- data/lib/oedipus/index.rb +62 -18
- data/lib/oedipus/rspec/test_harness.rb +1 -1
- data/lib/oedipus/version.rb +1 -1
- data/spec/integration/index_spec.rb +64 -35
- metadata +8 -8
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Oedipus: Sphinx 2 Search Client for Ruby
|
2
2
|
|
3
3
|
Oedipus is a client for the Sphinx search engine (>= 2.0.2), with support for
|
4
|
-
real-time indexes and multi and/or faceted searches.
|
4
|
+
real-time indexes and multi and/or multi-dimensional faceted searches.
|
5
5
|
|
6
6
|
It is not a clone of the PHP API, rather it is written from the ground up,
|
7
7
|
wrapping the SphinxQL API offered by searchd. Nor is it a plugin for
|
@@ -14,6 +14,11 @@ search may be implemented, while remaining light and simple.
|
|
14
14
|
Data structures are managed using core ruby data types (Array and Hash), ensuring
|
15
15
|
simplicity and flexibilty.
|
16
16
|
|
17
|
+
The current development focus is on supporting realtime indexes, where data is
|
18
|
+
indexed from your application, rather than by running the indexer tool that comes
|
19
|
+
with Sphinx. You may use indexes that are indexed with the indexer tool, but
|
20
|
+
Oedipus does not (yet) provide wrappers for indexing that data via ruby [1].
|
21
|
+
|
17
22
|
## Dependencies
|
18
23
|
|
19
24
|
* ruby (>= 1.9)
|
@@ -242,13 +247,16 @@ from the base query.
|
|
242
247
|
|
243
248
|
Oedipus allows you to replace '%{query}' in your facets with whatever was in the
|
244
249
|
original query. This can be useful if you want to provide facets that only
|
245
|
-
perform the search in the title of the document (`"@title (%{query})"`) for
|
250
|
+
perform the search in the title of the document (`"@title (%{query})"`) for
|
251
|
+
example.
|
246
252
|
|
247
|
-
Each facet is given a
|
253
|
+
Each facet is given a key, which is used to reference it in the results. This
|
254
|
+
key is any arbitrary object that can be used as a key in a ruby Hash. You may,
|
255
|
+
for example, use domain-specific objects as keys.
|
248
256
|
|
249
257
|
Sphinx optimizes the queries by figuring out what the common parts are. Currently
|
250
258
|
it does two optimizations, though in future this will likely improve further, so
|
251
|
-
using this technique to do your faceted searches is
|
259
|
+
using this technique to do your faceted searches is the correct approach.
|
252
260
|
|
253
261
|
``` ruby
|
254
262
|
results = sphinx[:articles].search(
|
@@ -283,12 +291,57 @@ results = sphinx[:articles].search(
|
|
283
291
|
# }
|
284
292
|
```
|
285
293
|
|
294
|
+
#### Multi-dimensional faceted search
|
295
|
+
|
296
|
+
If you can add facets to the root query, how about adding facets to the facets
|
297
|
+
themselves? Easy:
|
298
|
+
|
299
|
+
``` ruby
|
300
|
+
results = sphinx[:articles].search(
|
301
|
+
"badgers",
|
302
|
+
facets: {
|
303
|
+
popular: {
|
304
|
+
views: 100..10000,
|
305
|
+
facets: {
|
306
|
+
in_title: "@title (%{query})"
|
307
|
+
}
|
308
|
+
}
|
309
|
+
}
|
310
|
+
)
|
311
|
+
# => {
|
312
|
+
# total_found: 987,
|
313
|
+
# time: 0.000,
|
314
|
+
# records: [ ... ],
|
315
|
+
# facets: {
|
316
|
+
# popular: {
|
317
|
+
# total_found: 25,
|
318
|
+
# time: 0.000,
|
319
|
+
# records: [ ... ],
|
320
|
+
# facets: {
|
321
|
+
# in_title: {
|
322
|
+
# total_found: 24,
|
323
|
+
# time: 0.000,
|
324
|
+
# records: [ ... ]
|
325
|
+
# }
|
326
|
+
# }
|
327
|
+
# }
|
328
|
+
# }
|
329
|
+
# }
|
330
|
+
```
|
331
|
+
|
332
|
+
In the above example, the nested facet `:in_title` inherits the default
|
333
|
+
parameters from the facet `:popular`, which inherits its parameters from
|
334
|
+
the root query. The result is a search for "badgers" limited only to the
|
335
|
+
title, with views between 100 and 10000.
|
336
|
+
|
337
|
+
There is no limit imposed in Oedipus for how deeply facets can be nested.
|
338
|
+
|
286
339
|
### General purpose multi-search
|
287
340
|
|
288
341
|
If you want to execute multiple queries in a batch that are not related to each
|
289
342
|
other (which would be a faceted search), then you can use `#multi_search`.
|
290
343
|
|
291
|
-
You pass a Hash of
|
344
|
+
You pass a Hash of keyed-queries and get a Hash of keyed-resultsets.
|
292
345
|
|
293
346
|
``` ruby
|
294
347
|
results = sphinx[:articles].multi_search(
|
@@ -313,7 +366,7 @@ results = sphinx[:articles].multi_search(
|
|
313
366
|
|
314
367
|
There are both unit tests and integration tests in the specs/ directory. By default they
|
315
368
|
will both run, but in order for the integration specs to work, you need a locally
|
316
|
-
installed copy of [Sphinx] [
|
369
|
+
installed copy of [Sphinx] [2]. You then execute the specs as follows:
|
317
370
|
|
318
371
|
SEARCHD=/path/to/bin/searchd bundle exec rake spec
|
319
372
|
|
@@ -334,7 +387,9 @@ You may also compile the C extension and run the specs separately, if you prefer
|
|
334
387
|
|
335
388
|
### Footnotes
|
336
389
|
|
337
|
-
[1]:
|
390
|
+
[1]: In practice I find such an abstraction not to be very useful, as it assumes a single-server setup
|
391
|
+
|
392
|
+
[2]: You can build a local copy of sphinx without installing it on the system:
|
338
393
|
|
339
394
|
cd sphinx-2.0.4/
|
340
395
|
./configure
|
@@ -344,11 +399,10 @@ You may also compile the C extension and run the specs separately, if you prefer
|
|
344
399
|
|
345
400
|
## Future Plans
|
346
401
|
|
347
|
-
* Integration
|
402
|
+
* Integration ActiveRecord (DataMapper support has already been added)
|
348
403
|
* Support for re-indexing non-realtime indexes from ruby code
|
349
404
|
* Distributed index support (sharding writes between indexes)
|
350
405
|
* Make C extension optional and provide an implementation in pure-ruby
|
351
|
-
* N-dimensional faceted search (facets inside of facets)
|
352
406
|
* Query translation layer for Lucene-style AND/OR/NOT and attribute:value interpretation
|
353
407
|
* Fulltext query sanitization for unsafe user input (e.g. @@missing field)
|
354
408
|
|
data/lib/oedipus/index.rb
CHANGED
@@ -123,7 +123,7 @@ module Oedipus
|
|
123
123
|
# The results returned include a :facets key, containing the results for each facet.
|
124
124
|
#
|
125
125
|
# @example Performing a faceted search
|
126
|
-
# index.
|
126
|
+
# index.search(
|
127
127
|
# "cats | dogs",
|
128
128
|
# category_id: 7,
|
129
129
|
# facets: {
|
@@ -132,6 +132,26 @@ module Oedipus
|
|
132
132
|
# }
|
133
133
|
# )
|
134
134
|
#
|
135
|
+
# To perform an n-dimensional faceted search, add a :facets option to each
|
136
|
+
# facet. Each facet will inherit from its immediate parent, which inerits
|
137
|
+
# from its parent, up to the root query.
|
138
|
+
#
|
139
|
+
# @example Performing a n-dimensional faceted search
|
140
|
+
# index.search(
|
141
|
+
# "cats | dogs",
|
142
|
+
# facets: {
|
143
|
+
# popular: {
|
144
|
+
# views: Oedipus.gte(1000),
|
145
|
+
# facets: {
|
146
|
+
# in_title: "@title (%{query})"
|
147
|
+
# }
|
148
|
+
# }
|
149
|
+
# }
|
150
|
+
# )
|
151
|
+
#
|
152
|
+
# The results in a n-dimensional faceted search are returned with each set
|
153
|
+
# of facet results in turn containing a :facets element.
|
154
|
+
#
|
135
155
|
# @param [String] query
|
136
156
|
# a fulltext query
|
137
157
|
#
|
@@ -160,15 +180,7 @@ module Oedipus
|
|
160
180
|
# a Hash containing meta data, with the records in :records, and if any
|
161
181
|
# facets were included, the facets inside the :facets Hash
|
162
182
|
def search(*args)
|
163
|
-
|
164
|
-
main_query = [query, options.reject { |k, _| k == :facets }]
|
165
|
-
facets = merge_queries(main_query, options.fetch(:facets, {}))
|
166
|
-
|
167
|
-
{ facets: {} }.tap do |results|
|
168
|
-
multi_search({ _main_: main_query }.merge(facets)).each do |k, v|
|
169
|
-
k == :_main_ ? results.merge!(v) : results[:facets].merge!(k => v)
|
170
|
-
end
|
171
|
-
end
|
183
|
+
expand_facet_tree(multi_search(deep_merge_facets(args)))
|
172
184
|
end
|
173
185
|
|
174
186
|
# Perform a faceted search on the index, using a base query and one or more facets.
|
@@ -257,19 +269,51 @@ module Oedipus
|
|
257
269
|
end
|
258
270
|
|
259
271
|
case args[0]
|
260
|
-
when String then [args[0], args.fetch(1, {})]
|
261
|
-
when Hash then [default_query, args[0] ]
|
272
|
+
when String then [args[0], args.fetch(1, {}).dup]
|
273
|
+
when Hash then [default_query, args[0].dup ]
|
262
274
|
else raise ArgumentError, "Invalid query argument type #{args.first.class}"
|
263
275
|
end
|
264
276
|
end
|
265
277
|
|
266
|
-
def
|
267
|
-
|
278
|
+
def expand_facet_tree(result)
|
279
|
+
Hash[].tap do |tree|
|
280
|
+
result.each do |k, v|
|
281
|
+
t = tree
|
282
|
+
|
283
|
+
k.each do |name|
|
284
|
+
f = t[:facets] ||= {}
|
285
|
+
t = f[name] ||= {}
|
286
|
+
end
|
287
|
+
|
288
|
+
t.merge!(v)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
def deep_merge_facets(base_args, list = {}, path = [])
|
294
|
+
# FIXME: Try and make this shorter and more functional in style
|
295
|
+
base_query, base_options = extract_query_data(base_args)
|
296
|
+
|
297
|
+
facets = base_options.delete(:facets)
|
298
|
+
|
299
|
+
list.merge!(path => [base_query, base_options])
|
300
|
+
|
301
|
+
unless facets.nil?
|
302
|
+
facets.each do |k, q|
|
303
|
+
facet_query, facet_options = extract_query_data(q, base_query)
|
304
|
+
|
305
|
+
deep_merge_facets(
|
306
|
+
[
|
307
|
+
facet_query.gsub("%{query}", base_query),
|
308
|
+
base_options.merge(facet_options)
|
309
|
+
],
|
310
|
+
list,
|
311
|
+
path.dup << k
|
312
|
+
)
|
313
|
+
end
|
314
|
+
end
|
268
315
|
|
269
|
-
|
270
|
-
query, filters = extract_query_data(q, base_query)
|
271
|
-
[k, [query.gsub("%{query}", base_query), base_filters.merge(filters)]]
|
272
|
-
}]
|
316
|
+
list
|
273
317
|
end
|
274
318
|
end
|
275
319
|
end
|
data/lib/oedipus/version.rb
CHANGED
@@ -63,7 +63,7 @@ describe Oedipus::Index do
|
|
63
63
|
|
64
64
|
context "with a valid document ID" do
|
65
65
|
it "returns the matched document" do
|
66
|
-
index.fetch(2).should == { id: 2, views: 73, user_id: 0,
|
66
|
+
index.fetch(2).should == { id: 2, views: 73, user_id: 0, state: "" }
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
@@ -86,7 +86,7 @@ describe Oedipus::Index do
|
|
86
86
|
|
87
87
|
it "modifies the data" do
|
88
88
|
index.update(1, views: 721)
|
89
|
-
index.fetch(1).should == { id: 1, views: 721, user_id: 7,
|
89
|
+
index.fetch(1).should == { id: 1, views: 721, user_id: 7, state: "" }
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -123,7 +123,7 @@ describe Oedipus::Index do
|
|
123
123
|
|
124
124
|
it "entirely replaces the record" do
|
125
125
|
index.replace(1, title: "Badgers and foxes", views: 150)
|
126
|
-
index.fetch(1).should == { id: 1, views: 150, user_id: 0,
|
126
|
+
index.fetch(1).should == { id: 1, views: 150, user_id: 0, state: "" }
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
@@ -134,7 +134,7 @@ describe Oedipus::Index do
|
|
134
134
|
|
135
135
|
it "entirely replaces the record" do
|
136
136
|
index.replace(2, title: "Beer and wine", views: 15)
|
137
|
-
index.fetch(2).should == { id: 2, views: 15, user_id: 0,
|
137
|
+
index.fetch(2).should == { id: 2, views: 15, user_id: 0, state: "" }
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
@@ -181,9 +181,9 @@ describe Oedipus::Index do
|
|
181
181
|
|
182
182
|
it "includes the matches records" do
|
183
183
|
index.search("badgers")[:records].should == [
|
184
|
-
{ id: 1, views: 150, user_id: 0,
|
185
|
-
{ id: 3, views: 41, user_id: 0,
|
186
|
-
{ id: 4, views: 3003, user_id: 0,
|
184
|
+
{ id: 1, views: 150, user_id: 0, state: "" },
|
185
|
+
{ id: 3, views: 41, user_id: 0, state: "" },
|
186
|
+
{ id: 4, views: 3003, user_id: 0, state: "" }
|
187
187
|
]
|
188
188
|
end
|
189
189
|
end
|
@@ -195,19 +195,19 @@ describe Oedipus::Index do
|
|
195
195
|
|
196
196
|
it "includes the matches records" do
|
197
197
|
index.search(views: 40..90)[:records].should == [
|
198
|
-
{ id: 2, views: 87, user_id: 0,
|
199
|
-
{ id: 3, views: 41, user_id: 0,
|
198
|
+
{ id: 2, views: 87, user_id: 0, state: "" },
|
199
|
+
{ id: 3, views: 41, user_id: 0, state: "" }
|
200
200
|
]
|
201
201
|
end
|
202
202
|
|
203
203
|
pending "the sphinxql grammar does not currently support this, though I'm patching it" do
|
204
204
|
context "with string attributes" do
|
205
205
|
before(:each) do
|
206
|
-
index.insert(5, title: "No more badgers, please", views: 0,
|
206
|
+
index.insert(5, title: "No more badgers, please", views: 0, state: "new")
|
207
207
|
end
|
208
208
|
|
209
209
|
it "filters by the string attribute" do
|
210
|
-
index.search(
|
210
|
+
index.search(state: "new")[:records].should == [{ id: 5, views: 0, user_id: 0, state: "new" }]
|
211
211
|
end
|
212
212
|
end
|
213
213
|
end
|
@@ -220,8 +220,8 @@ describe Oedipus::Index do
|
|
220
220
|
|
221
221
|
it "includes the matches records" do
|
222
222
|
index.search("badgers", views: Oedipus.gt(100))[:records].should == [
|
223
|
-
{ id: 1, views: 150, user_id: 0,
|
224
|
-
{ id: 4, views: 3003, user_id: 0,
|
223
|
+
{ id: 1, views: 150, user_id: 0, state: "" },
|
224
|
+
{ id: 4, views: 3003, user_id: 0, state: "" }
|
225
225
|
]
|
226
226
|
end
|
227
227
|
end
|
@@ -233,14 +233,14 @@ describe Oedipus::Index do
|
|
233
233
|
|
234
234
|
it "returns the limited subset of the results" do
|
235
235
|
index.search("badgers", limit: 2)[:records].should == [
|
236
|
-
{ id: 1, views: 150, user_id: 0,
|
237
|
-
{ id: 3, views: 41, user_id: 0,
|
236
|
+
{ id: 1, views: 150, user_id: 0, state: "" },
|
237
|
+
{ id: 3, views: 41, user_id: 0, state: "" }
|
238
238
|
]
|
239
239
|
end
|
240
240
|
|
241
241
|
it "can use an offset" do
|
242
242
|
index.search("badgers", limit: 1, offset: 1)[:records].should == [
|
243
|
-
{ id: 3, views: 41, user_id: 0,
|
243
|
+
{ id: 3, views: 41, user_id: 0, state: "" }
|
244
244
|
]
|
245
245
|
end
|
246
246
|
end
|
@@ -248,9 +248,9 @@ describe Oedipus::Index do
|
|
248
248
|
context "with ordering" do
|
249
249
|
it "returns the results ordered accordingly" do
|
250
250
|
index.search("badgers", order: {views: :desc})[:records].should == [
|
251
|
-
{ id: 4, views: 3003, user_id: 0,
|
252
|
-
{ id: 1, views: 150, user_id: 0,
|
253
|
-
{ id: 3, views: 41, user_id: 0,
|
251
|
+
{ id: 4, views: 3003, user_id: 0, state: "" },
|
252
|
+
{ id: 1, views: 150, user_id: 0, state: "" },
|
253
|
+
{ id: 3, views: 41, user_id: 0, state: "" },
|
254
254
|
]
|
255
255
|
end
|
256
256
|
|
@@ -265,9 +265,9 @@ describe Oedipus::Index do
|
|
265
265
|
context "with attribute additions" do
|
266
266
|
it "fetches the additional attributes" do
|
267
267
|
index.search("badgers", attrs: [:*, "7 AS x"])[:records].should == [
|
268
|
-
{ id: 1, views: 150, user_id: 0,
|
269
|
-
{ id: 3, views: 41, user_id: 0,
|
270
|
-
{ id: 4, views: 3003, user_id: 0,
|
268
|
+
{ id: 1, views: 150, user_id: 0, state: "", x: 7 },
|
269
|
+
{ id: 3, views: 41, user_id: 0, state: "", x: 7 },
|
270
|
+
{ id: 4, views: 3003, user_id: 0, state: "", x: 7 },
|
271
271
|
]
|
272
272
|
end
|
273
273
|
end
|
@@ -304,19 +304,19 @@ describe Oedipus::Index do
|
|
304
304
|
|
305
305
|
it "returns the main results in the top-level" do
|
306
306
|
results[:records].should == [
|
307
|
-
{ id: 1, views: 150, user_id: 1,
|
308
|
-
{ id: 3, views: 41, user_id: 2,
|
309
|
-
{ id: 4, views: 3003, user_id: 1,
|
307
|
+
{ id: 1, views: 150, user_id: 1, state: "" },
|
308
|
+
{ id: 3, views: 41, user_id: 2, state: "" },
|
309
|
+
{ id: 4, views: 3003, user_id: 1, state: "" }
|
310
310
|
]
|
311
311
|
end
|
312
312
|
|
313
313
|
it "applies the filters on top of the base query" do
|
314
314
|
results[:facets][:popular][:records].should == [
|
315
|
-
{ id: 1, views: 150, user_id: 1,
|
316
|
-
{ id: 4, views: 3003, user_id: 1,
|
315
|
+
{ id: 1, views: 150, user_id: 1, state: "" },
|
316
|
+
{ id: 4, views: 3003, user_id: 1, state: "" }
|
317
317
|
]
|
318
318
|
results[:facets][:di_carla][:records].should == [
|
319
|
-
{ id: 3, views: 41, user_id: 2,
|
319
|
+
{ id: 3, views: 41, user_id: 2, state: "" }
|
320
320
|
]
|
321
321
|
end
|
322
322
|
end
|
@@ -334,7 +334,7 @@ describe Oedipus::Index do
|
|
334
334
|
|
335
335
|
it "applies the filters on top of the base query" do
|
336
336
|
results[:facets][:di_carla][:records].should == [
|
337
|
-
{ id: 3, views: 41, user_id: 2,
|
337
|
+
{ id: 3, views: 41, user_id: 2, state: "" }
|
338
338
|
]
|
339
339
|
end
|
340
340
|
end
|
@@ -351,7 +351,7 @@ describe Oedipus::Index do
|
|
351
351
|
|
352
352
|
it "entirely replaces the base query" do
|
353
353
|
results[:facets][:rabbits][:records].should == [
|
354
|
-
{ id: 2, views: 87, user_id: 1,
|
354
|
+
{ id: 2, views: 87, user_id: 1, state: "" }
|
355
355
|
]
|
356
356
|
end
|
357
357
|
end
|
@@ -368,7 +368,36 @@ describe Oedipus::Index do
|
|
368
368
|
|
369
369
|
it "merges the queries" do
|
370
370
|
results[:facets][:in_body][:records].should == [
|
371
|
-
{ id: 1, views: 150, user_id: 1,
|
371
|
+
{ id: 1, views: 150, user_id: 1, state: "" },
|
372
|
+
]
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
context "with multi-dimensional facets" do
|
377
|
+
let(:results) do
|
378
|
+
index.search(
|
379
|
+
"badgers",
|
380
|
+
facets: {
|
381
|
+
popular: {
|
382
|
+
views: Oedipus.gte(50),
|
383
|
+
facets: {
|
384
|
+
with_foxes: "%{query} & foxes"
|
385
|
+
}
|
386
|
+
},
|
387
|
+
}
|
388
|
+
)
|
389
|
+
end
|
390
|
+
|
391
|
+
it "merges the results in the outer facets" do
|
392
|
+
results[:facets][:popular][:records].should == [
|
393
|
+
{ id: 1, views: 150, user_id: 1, state: "" },
|
394
|
+
{ id: 4, views: 3003, user_id: 1, state: "" }
|
395
|
+
]
|
396
|
+
end
|
397
|
+
|
398
|
+
it "merges the results in the inner facets" do
|
399
|
+
results[:facets][:popular][:facets][:with_foxes][:records].should == [
|
400
|
+
{ id: 1, views: 150, user_id: 1, state: "" }
|
372
401
|
]
|
373
402
|
end
|
374
403
|
end
|
@@ -398,12 +427,12 @@ describe Oedipus::Index do
|
|
398
427
|
rabbits: "rabbits"
|
399
428
|
)
|
400
429
|
results[:badgers][:records].should == [
|
401
|
-
{ id: 1, views: 150, user_id: 1,
|
402
|
-
{ id: 3, views: 41, user_id: 2,
|
403
|
-
{ id: 4, views: 3003, user_id: 1,
|
430
|
+
{ id: 1, views: 150, user_id: 1, state: "" },
|
431
|
+
{ id: 3, views: 41, user_id: 2, state: "" },
|
432
|
+
{ id: 4, views: 3003, user_id: 1, state: "" }
|
404
433
|
]
|
405
434
|
results[:rabbits][:records].should == [
|
406
|
-
{ id: 2, views: 87, user_id: 1,
|
435
|
+
{ id: 2, views: 87, user_id: 1, state: "" }
|
407
436
|
]
|
408
437
|
end
|
409
438
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oedipus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-05-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &20757600 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *20757600
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake-compiler
|
27
|
-
requirement: &
|
27
|
+
requirement: &20756700 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *20756700
|
36
36
|
description: ! "== Sphinx 2 Comes to Ruby\n\nOedipus brings full support for Sphinx
|
37
37
|
2 to Ruby:\n\n - real-time indexes (insert, replace, update, delete)\n - faceted
|
38
38
|
search (variations on a base query)\n - multi-queries (multiple queries executed
|
@@ -109,7 +109,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
109
109
|
version: '0'
|
110
110
|
segments:
|
111
111
|
- 0
|
112
|
-
hash:
|
112
|
+
hash: -1569263709563515069
|
113
113
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
114
|
none: false
|
115
115
|
requirements:
|
@@ -118,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
118
|
version: '0'
|
119
119
|
segments:
|
120
120
|
- 0
|
121
|
-
hash:
|
121
|
+
hash: -1569263709563515069
|
122
122
|
requirements: []
|
123
123
|
rubyforge_project: oedipus
|
124
124
|
rubygems_version: 1.8.11
|