Skip to content

Commit

Permalink
Unhelpfully incomplete and undocumented initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
jaylett committed Dec 1, 2011
0 parents commit e6b5c44
Show file tree
Hide file tree
Showing 16 changed files with 1,438 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.pyc
15 changes: 15 additions & 0 deletions searchify/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Note that much of the time, something that's a singleton (eg: a string) can also be an iterable. Where this isn't the case, it probably should be.
# In your search field names, don't start with an underscore ('_') as that's reserved.
# We STRONGLY recommend explicitly declaring your search field names, as it makes the resultant search system more useful to users. In some cases you don't need it, but that's rare.
# Note that strictly you can have a callable as a django_field directly. In this case, it will be called with a parameter of None to generate the search field name (well, part of it - it only needs to be unique to the class). But don't do this, it's ugly.
# When auto-generating, we use '.' to separate bits of things where possible, and '__' where we require \w only.

# FIXME: document the query() method added to managers
# FIXME: make query() do pagination properly, on top of anything Flax chooses to offer us (currently Flax gives us nothing)
# FIXME: detect and resolve circular cascades

# TODO: make it possible to index an individual model to more than one database. (Probably multiple explicit indexers.)
# TODO: reverse cascades, so you can put searchable stuff into your Profile model, but have it index stuff from the User. (Also just easier in general, although I can't see how to make it as powerful as normal cascades.)
# TODO: if you change the django_fields, searchify should "want" to reindex, with suitable options to tell it not to; perhaps a hash of the config (and allow it to be set explicitly for people who want to manage this themselves)

from index import register_indexer, autodiscover, reindex, Indexer, get_searcher
30 changes: 30 additions & 0 deletions searchify/clients/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""This module contains the clients which talk to search systems.
Currently there is decent support for pyes, and some old and flaky support for
Xappy and Flax.
"""

from django.conf import settings
from django.core.exceptions import ImproperlyConfigured

import os.path


def import_client(engine):
"""Import a lib.searchify client."""

mod = __import__(engine + '_client', globals(), locals(),
fromlist=['Client'], level=1)
return mod.Client


if hasattr(settings, 'ENABLE_SEARCHIFY') and settings.ENABLE_SEARCHIFY:
engine = getattr(settings, "SEARCHIFY_ENGINE", None)
if engine is None:
raise ImproperlyConfigured('No engine configured for searchify: '
'specify settings.SEARCHIFY_ENGINE')

Client = import_client(engine)
else:
Client = import_client('unconfigured')
68 changes: 68 additions & 0 deletions searchify/clients/flax_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""Searchify client using Flax as a backend.
Status: dubious - use with caution.
"""

from django.conf import settings
from flax.searchclient import Client, FlaxError

def ClientFactory(dbname):
personal_prefix = getattr(settings, "FLAX_PERSONAL_PREFIX", "")
return FlaxClient(personal_prefix + dbname, settings.FLAX_BASE_URL)

class FlaxClient:
Error = FlaxError
def __init__(self, dbname, url):
self.client = Client(url)
self.dbname = dbname

def create(self, fields, reopen=False, overwrite=False):
# print "making db"
self.client.create_database(self.dbname, reopen=reopen, overwrite=overwrite)
# print "done."
schema = self.schema()
for f,c in fields.items():
# print "adding field %s (%s)" % (f, c)
c = dict(c)
if c.has_key("freetext") and c['freetext']:
if c['freetext'].has_key("weight"):
c['freetext']['term_frequency_multiplier'] = c['freetext']['weight']
del c['freetext']['weight']
schema.add_field(f, c)

def schema(self):
return self.client.schema(self.dbname)

def add(self, doc, docid=None):
db = self.client.db(self.dbname)
# print "adding doc",
ret = db.add_document(doc, docid)
# print "done."
return ret

def search(self, query, query_filter=None, start=0, end=10):
if filter:
return self.client.db(self.dbname).search_structured(query_any=query, filter=query_filter, start_rank=start, end_rank=end)
else:
return self.client.db(self.dbname).search_simple(query, start, end)

def get_searcher(self):
"""
Return some sort of useful searching object.
"""
return self.client.db(self.dbname)

def delete(self, uid):
db = self.client.db(self.dbname)
ret = db.delete_document(uid)
return ret

def flush(self):
db = self.client.db(self.dbname)
db.flush()

def close(self):
self.flush()
self.client.close()
self.client = None
Loading

0 comments on commit e6b5c44

Please sign in to comment.