[Checkins] SVN: hurry.query/trunk/ Allow to sort on a given index, optionally limiting and reversing the ordered resultset. Bump the future version to 1.1 now that we implemeted addtional features.
Jan-Wijbrand Kolman
janwijbrand at gmail.com
Wed Jun 9 04:36:49 EDT 2010
Log message for revision 113300:
Allow to sort on a given index, optionally limiting and reversing the ordered resultset. Bump the future version to 1.1 now that we implemeted addtional features.
Changed:
U hurry.query/trunk/CHANGES.txt
U hurry.query/trunk/setup.py
U hurry.query/trunk/src/hurry/query/query.py
U hurry.query/trunk/src/hurry/query/query.txt
-=-
Modified: hurry.query/trunk/CHANGES.txt
===================================================================
--- hurry.query/trunk/CHANGES.txt 2010-06-09 06:52:09 UTC (rev 113299)
+++ hurry.query/trunk/CHANGES.txt 2010-06-09 08:36:49 UTC (rev 113300)
@@ -1,9 +1,17 @@
CHANGES
=======
-1.0.1 (unreleased)
+1.1.0 (unreleased)
------------------
+* Allow the searchResults method of a Query to take an additional keyword
+ argument `sort_field` that defines that defines (catalog_name, index_name) to
+ sort on. That index in that catalog should implement IIndexSort.
+
+ In addition to this keyword argument, `limit` and `reverse` keyword arguments
+ can be passed too, that will limit the sorted resultset and/or reverse its
+ order.
+
* Allow the searchResults method of a Query object to take an additional
optional context argument. This context will determine which catalog
the search is performed on.
Modified: hurry.query/trunk/setup.py
===================================================================
--- hurry.query/trunk/setup.py 2010-06-09 06:52:09 UTC (rev 113299)
+++ hurry.query/trunk/setup.py 2010-06-09 08:36:49 UTC (rev 113300)
@@ -25,7 +25,7 @@
setup(
name="hurry.query",
- version = '1.0.1dev',
+ version = '1.1.0dev',
author='Infrae',
author_email='faassen at startifact.com',
description="Higher level query system for the zope.catalog",
Modified: hurry.query/trunk/src/hurry/query/query.py
===================================================================
--- hurry.query/trunk/src/hurry/query/query.py 2010-06-09 06:52:09 UTC (rev 113299)
+++ hurry.query/trunk/src/hurry/query/query.py 2010-06-09 08:36:49 UTC (rev 113300)
@@ -26,7 +26,7 @@
from zope.component import getUtility
from zope.interface import implements
from zope.intid.interfaces import IIntIds
-
+from zope.index.interfaces import IIndexSort
from hurry.query import interfaces
# XXX look into using multiunion for performance?
@@ -34,14 +34,29 @@
class Query(object):
implements(interfaces.IQuery)
- def searchResults(self, query, context=None):
+ def searchResults(
+ self, query, context=None, sort_field=None, limit=None, reverse=False):
+
results = query.apply(context)
- if results is not None:
- uidutil = getUtility(IIntIds, '', context)
- results = ResultSet(results, uidutil)
- return results
+ if results is None:
+ return
+ if sort_field is not None:
+ catalog_name, index_name = sort_field
+ catalog = getUtility(ICatalog, catalog_name, context)
+ index = catalog[index_name]
+ if not IIndexSort.providedBy(index):
+ raise ValueError(
+ 'Index %s in catalog %s does not support '
+ 'sorting.' % (index_name, catalog_name))
+ results = list(index.sort(results, limit=limit, reverse=reverse))
+ # Note: in case no sort_field is provided, the resultset order
+ # is undefined. As such limiting and reverse does not have any
+ # practical meaning.
+ uidutil = getUtility(IIntIds, '', context)
+ return ResultSet(results, uidutil)
+
class Term(object):
def __and__(self, other):
Modified: hurry.query/trunk/src/hurry/query/query.txt
===================================================================
--- hurry.query/trunk/src/hurry/query/query.txt 2010-06-09 06:52:09 UTC (rev 113299)
+++ hurry.query/trunk/src/hurry/query/query.txt 2010-06-09 08:36:49 UTC (rev 113300)
@@ -439,3 +439,79 @@
>>> displayQuery(In(f1, ['A', 'B']), context=site1)
[1, 2]
+
+Sorting and limiting the resultset
+----------------------------------
+
+It's possible to have the resultset sorted on one of the fields in the query.
+
+ >>> catalog = Catalog()
+ >>> provideUtility(catalog, ICatalog, 'catalog1')
+ >>> catalog['f1'] = FieldIndex('f1', IContent)
+ >>> catalog['f2'] = FieldIndex('f2', IContent)
+ >>> catalog['t'] = TextIndex('t1', IContent)
+
+First let's set up some new data::
+
+ >>> content = [
+ ... Content(1, 'a', 2, t1='Beautiful is better than ugly.'),
+ ... Content(2, 'a', 3, t1='Explicit is better than implicit'),
+ ... Content(3, 'b', 9, t1='Simple is better than complex'),
+ ... Content(4, 'c', 8, t1='Complex is better than complicated'),
+ ... Content(5, 'c', 7, t1='Readability counts'),
+ ... Content(6, 'a', 1, t1='Although practicality beats purity')]
+
+And catalog them now::
+
+ >>> for entry in content:
+ ... catalog.index_doc(intid.register(entry), entry)
+
+Define a convenience function for quickly displaying a result set without
+performing any sorting here ourselves.
+
+ >>> def displayResult(q, context=None, **kw):
+ ... query = getUtility(IQuery)
+ ... r = query.searchResults(q, context, **kw)
+ ... return [e.id for e in r]
+
+
+Without using sorting in the query itself, the resultset has an undefined
+order. We "manually" sort the results here to have something testable.
+
+ >>> f1 = ('catalog1', 'f1')
+ >>> [r for r in sorted(displayResult(Eq(f1, 'a')))]
+ [1, 2, 6]
+
+Now we sort on the f2 index.
+
+ >>> f1 = ('catalog1', 'f1')
+ >>> displayResult(Eq(f1, 'a'), sort_field=('catalog1', 'f2'))
+ [6, 1, 2]
+
+Reverse the order.
+
+ >>> f1 = ('catalog1', 'f1')
+ >>> displayResult(Eq(f1, 'a'), sort_field=('catalog1', 'f2'), reverse=True)
+ [2, 1, 6]
+
+We can limit the amount of found items.
+
+ >>> f1 = ('catalog1', 'f1')
+ >>> displayResult(Eq(f1, 'a'), sort_field=('catalog1', 'f2'), limit=2)
+ [6, 1]
+
+We can limit the reversed resultset too.
+
+ >>> f1 = ('catalog1', 'f1')
+ >>> displayResult(
+ ... Eq(f1, 'a'), sort_field=('catalog1', 'f2'), limit=2, reverse=True)
+ [2, 1]
+
+Whenever a field is used for sorting that does not support is, an error is
+raised.
+
+ >>> f1 = ('catalog1', 'f1')
+ >>> displayResult(Eq(f1, 'a'), sort_field=('catalog1', 't'))
+ Traceback (most recent call last):
+ ...
+ ValueError: Index t in catalog catalog1 does not support sorting.
More information about the checkins
mailing list