oedipus 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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
|