oedipus is a friendlier API for the Sphinx search server. It presents a similar API to elasticutils, giving you the option of switching back and forth between Sphinx and elasticsearch at the flip of a switch, as long as you stick to the common subset of functionality.
- Django, unless you're willing to implement some of the Django model API on your own model objects. There's no way to get useful non-integer information out of Sphinx on its own, so we use the passed-in model objects to query a secondary DB.
sphinxapi.py, the Python module from the Sphinx source code distribution
Limitations Compared to elasticutils
Because Sphinx itself is less flexible than ElasticSearch, oedipus can't offer all the features of elasticutils' full API.
query() is Less Controllable
Sphinx takes just a query string and bangs it against all indexed
fields. ElasticSearch, on the other hand, lets you specify which
fields to match against per call. This makes the use of
between the two necessarily inconsistent:
query()takes a single argument, which matches against all fields, Sphinx-style:
query()takes an arbitrary number of keyword args, one per field to match against:
Thus, if you want to maintain the ability to switch quickly between Sphinx and ElasticSearch, simply combine the two:
No Or-ing of Filters
There's no way to "or" arbitrary filters together in Sphinx, so
oedipus does not support elasticutils'
F objects. However, you can
S(Animal).filter(color__in=[12, 34, 56])
lte lookups but not
just because that's what Sphinx directly supports. Add it for integers
if it bothers you. Floats (
SetFilterFloatRange()) are trickier.
If you call
values(), you must pass in a list of fields. In
elasticutils, this is optional.
There isn't any, because Sphinx doesn't support it.
SphinxMeta class defined on the model with the
The index to use.
The name of the attribute holding the ID of the DB object which should be returned by search results. You don't need to specify this unless the object ID differs from the Sphinx document ID.
Dict mapping field name to converter to use.
Dict mapping field name to weight
Single string for which field to sort by, or list of fields to sort by.
Excerpt-related values to use.
excerpt_before_match-- text to go before an excerpt
excerpt_after_match-- text to go after an exceprt
excerpt_limit-- limit of characters in an excerpt
Tuple of (field to group on, sort order).
Examples:group_by = ('a', '@group') group_by = ('a', '-@group')
Other Behavior Notes
order_by() calls pave over the effect of previous
calls. Ordering defaults to most-relevant-first.
Running the Tests
Install the packages listed in requirements.txt using pip:
pip install -r requirements.txt
Run the tests using nose:
Beware that if you run the support.mozilla.com tests, they will clear out your Sphinx indices. Don't be surprised.
- Support for the rest of the Sphinx API would be nice: SetGroupDistinct, SetFilterFloatRange, SetIDRange, and everything else at http://sphinxsearch.com/docs/manual-0.9.9.html. I don't plan to add it, because I don't need it, but patches are welcome.
- Decouple the SphinxMeta classes from the models. We should have a nice way of assigning Sphinx metadata to third-party models that we can't just scribble on. Then we won't need to depend on Django.
- Think about mapping oedipus 1-arg queries to ElasticSearch
_allqueries. We might need to add some support to elasticutils first.
- Make sure we always throw nice errors when someone tries to do
elasticutils-ish things not supported by Sphinx, like passing