[ckan-changes] commit/ckan: John Glover: [solr] Fix tag searching using Postgres
Bitbucket
commits-noreply at bitbucket.org
Mon Aug 22 15:50:48 UTC 2011
1 new changeset in ckan:
http://bitbucket.org/okfn/ckan/changeset/b2c7b5945784/
changeset: b2c7b5945784
branch: feature-1275-solr-search
user: John Glover
date: 2011-08-22 17:50:27
summary: [solr] Fix tag searching using Postgres
affected #: 3 files (3.4 KB)
--- a/ckan/lib/search/__init__.py Mon Aug 22 14:51:46 2011 +0100
+++ b/ckan/lib/search/__init__.py Mon Aug 22 16:50:27 2011 +0100
@@ -5,7 +5,7 @@
from ckan.lib.dictization.model_dictize import package_to_api1
from common import SearchError
from index import PackageSearchIndex, NoopSearchIndex
-from query import PackageSearchQuery, QueryOptions
+from query import TagSearchQuery, PackageSearchQuery, QueryOptions
log = logging.getLogger(__name__)
@@ -28,6 +28,7 @@
}
_QUERIES = {
+ 'tag': TagSearchQuery,
'package': PackageSearchQuery
}
--- a/ckan/lib/search/query.py Mon Aug 22 14:51:46 2011 +0100
+++ b/ckan/lib/search/query.py Mon Aug 22 16:50:27 2011 +0100
@@ -182,11 +182,89 @@
def _run(self):
raise SearchError("SearchQuery._run() not implemented!")
+
+ def _db_query(self, q):
+ # Run the query
+ self.count = q.count()
+ q = q.offset(self.options.get('offset'))
+ q = q.limit(self.options.get('limit'))
+
+ self.results = []
+ for result in q:
+ if isinstance(result, tuple) and isinstance(result[0], model.DomainObject):
+ # This is the case for order_by rank due to the add_column.
+ self.results.append(result[0])
+ else:
+ self.results.append(result)
# convenience, allows to query(..)
__call__ = run
+# TODO: is this code used anywhere? If so, fix it write some tests for it.
+# class GroupSqlSearchQuery(SearchQuery):
+# """ Search for groups in plain SQL. """
+# def _run(self):
+# if not self.query.terms:
+# return
+# q = authz.Authorizer().authorized_query(username, model.Group)
+# for term in self.query.terms:
+# q = query.filter(model.Group.name.contains(term.lower()))
+# self._db_query(q)
+
+
+class TagSearchQuery(SearchQuery):
+ """Search for tags in plain SQL."""
+ def _run(self):
+ q = model.Session.query(model.Tag)
+ q = q.distinct().join(model.Tag.package_tags)
+ terms = list(self.query.terms)
+ for field, value in self.query.fields.items():
+ if field in ('tag', 'tags'):
+ terms.append(value)
+ if not len(terms):
+ return
+ for term in terms:
+ q = q.filter(model.Tag.name.contains(term.lower()))
+ self._db_query(q)
+
+
+# class ResourceSqlSearchQuery(SqlSearchQuery):
+# """ Search for resources in plain SQL. """
+
+# def _run(self):
+# q = model.Session.query(model.Resource) # TODO authz
+# if self.query.terms:
+# raise SearchError('Only field specific terms allowed in resource search.')
+# #self._check_options_specified_are_allowed('resource search', ['all_fields', 'offset', 'limit'])
+# self.options.ref_entity_with_attr = 'id' # has no name
+# resource_fields = model.Resource.get_columns()
+# for field, terms in self.query.fields.items():
+# if isinstance(terms, basestring):
+# terms = terms.split()
+# if field not in resource_fields:
+# raise SearchError('Field "%s" not recognised in Resource search.' % field)
+# for term in terms:
+# model_attr = getattr(model.Resource, field)
+# if field == 'hash':
+# q = q.filter(model_attr.ilike(unicode(term) + '%'))
+# elif field in model.Resource.get_extra_columns():
+# model_attr = getattr(model.Resource, 'extras')
+
+# like = or_(model_attr.ilike(u'''%%"%s": "%%%s%%",%%''' % (field, term)),
+# model_attr.ilike(u'''%%"%s": "%%%s%%"}''' % (field, term))
+# )
+# q = q.filter(like)
+# else:
+# q = q.filter(model_attr.ilike('%' + unicode(term) + '%'))
+
+# order_by = self.options.order_by
+# if order_by is not None:
+# if hasattr(model.Resource, order_by):
+# q = q.order_by(getattr(model.Resource, order_by))
+# self._db_query(q)
+
+
class PackageSearchQuery(SearchQuery):
def _run(self):
fq = ""
--- a/ckan/tests/functional/api/test_action.py Mon Aug 22 14:51:46 2011 +0100
+++ b/ckan/tests/functional/api/test_action.py Mon Aug 22 16:50:27 2011 +0100
@@ -2,6 +2,8 @@
from pprint import pprint, pformat
from nose.tools import assert_equal
+from ckan import plugins
+import ckan.lib.search as search
from ckan.lib.create_test_data import CreateTestData
import ckan.model as model
from ckan.tests import WsgiAppCase
@@ -22,15 +24,16 @@
@classmethod
def setup_class(self):
+ search.clear()
+ plugins.load('synchronous_search')
CreateTestData.create()
-
self.sysadmin_user = model.User.get('testsysadmin')
-
self.normal_user = model.User.get('annafan')
@classmethod
def teardown_class(self):
model.repo.rebuild_db()
+ search.clear()
def test_01_package_list(self):
postparams = '%s=1' % json.dumps({})
@@ -461,6 +464,7 @@
postparams = '%s=1' % json.dumps({'q':'r'})
res = self.app.post('/api/action/tag_autocomplete', params=postparams)
res_obj = json.loads(res.body)
+ print res_obj
assert res_obj == {
'help': 'Returns tags containing the provided string',
'result': ['russian'],
Repository URL: https://bitbucket.org/okfn/ckan/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the ckan-changes
mailing list