[Checkins] SVN: zope.app.catalog/branches/nadako-sorting/ Create a branch for implement sorting/limiting/reversing resultsets
Dan Korostelev
nadako at gmail.com
Sat Dec 27 17:06:40 EST 2008
Log message for revision 94395:
Create a branch for implement sorting/limiting/reversing resultsets
Changed:
A zope.app.catalog/branches/nadako-sorting/
U zope.app.catalog/branches/nadako-sorting/CHANGES.txt
U zope.app.catalog/branches/nadako-sorting/buildout.cfg
U zope.app.catalog/branches/nadako-sorting/src/zope/app/catalog/README.txt
U zope.app.catalog/branches/nadako-sorting/src/zope/app/catalog/catalog.py
U zope.app.catalog/branches/nadako-sorting/src/zope/app/catalog/interfaces.py
-=-
Property changes on: zope.app.catalog/branches/nadako-sorting
___________________________________________________________________
Added: svn:ignore
+ bin
build
dist
lib
develop-eggs
eggs
parts
.installed.cfg
Added: svn:externals
+ zope.index-sorting svn://svn.zope.org/repos/main/zope.index/branches/nadako-sorting
Modified: zope.app.catalog/branches/nadako-sorting/CHANGES.txt
===================================================================
--- zope.app.catalog/trunk/CHANGES.txt 2008-12-27 21:06:10 UTC (rev 94387)
+++ zope.app.catalog/branches/nadako-sorting/CHANGES.txt 2008-12-27 22:06:40 UTC (rev 94395)
@@ -2,9 +2,11 @@
CHANGES
=======
-3.5.2 (unreleased)
+3.6.0 (unreleased)
------------------
+- Add support for sorting, reversing and limiting result set,
+ using new zope.index IIndexSort features.
- Remove testing dependencies from install_requires.
3.5.1 (2007-10-31)
Modified: zope.app.catalog/branches/nadako-sorting/buildout.cfg
===================================================================
--- zope.app.catalog/trunk/buildout.cfg 2008-12-27 21:06:10 UTC (rev 94387)
+++ zope.app.catalog/branches/nadako-sorting/buildout.cfg 2008-12-27 22:06:40 UTC (rev 94395)
@@ -1,5 +1,5 @@
[buildout]
-develop = .
+develop = . zope.index-sorting
parts = test
[test]
Modified: zope.app.catalog/branches/nadako-sorting/src/zope/app/catalog/README.txt
===================================================================
--- zope.app.catalog/trunk/src/zope/app/catalog/README.txt 2008-12-27 21:06:10 UTC (rev 94387)
+++ zope.app.catalog/branches/nadako-sorting/src/zope/app/catalog/README.txt 2008-12-27 22:06:40 UTC (rev 94395)
@@ -22,6 +22,7 @@
... zope.interface.implements(
... zope.index.interfaces.IInjection,
... zope.index.interfaces.IIndexSearch,
+ ... zope.index.interfaces.IIndexSort,
... )
...
... def clear(self):
@@ -53,6 +54,12 @@
... if set is None:
... set = BTrees.IFBTree.IFTreeSet()
... return set
+ ...
+ ... def sort(self, docids, limit=None, reverse=False):
+ ... for i, docid in enumerate(sorted(docids, key=self.backward.get, reverse=reverse)):
+ ... yield docid
+ ... if limit and i >= (limit - 1):
+ ... break
The class implements `IInjection` to allow values to be indexed and
unindexed and `IIndexSearch` to support searching via the `apply`
@@ -227,6 +234,54 @@
>>> list(result) == [o4, o5]
True
+The searchResults method also provides a way to sort, limit and reverse
+results.
+
+When not using sorting, limiting and reversing are done by simple slicing
+and list reversing.
+
+ >>> list(cat.searchResults(size=5, _reverse=True)) == [o5, o4]
+ True
+
+ >>> list(cat.searchResults(size=5, _limit=1)) == [o4]
+ True
+
+ >>> list(cat.searchResults(size=5, _limit=1, _reverse=True)) == [o5]
+ True
+
+However, when using sorting by index, the limit and reverse parameters
+are passed to the index ``sort`` method so it can do it efficiently.
+
+Let's index more objects to work with:
+
+ >>> o7 = DiscriminatingPerson(7, 'blue')
+ >>> o8 = DiscriminatingPerson(3, 'blue')
+ >>> o9 = DiscriminatingPerson(14, 'blue')
+ >>> o10 = DiscriminatingPerson(1, 'blue')
+ >>> ids.data.update({7: o7, 8: o8, 9: o9, 10: o10})
+ >>> cat.index_doc(7, o7)
+ >>> cat.index_doc(8, o8)
+ >>> cat.index_doc(9, o9)
+ >>> cat.index_doc(10, o10)
+
+Now we can search all people who like blue, ordered by age:
+
+ >>> results = list(cat.searchResults(color='blue', _sort_index='age'))
+ >>> results == [o3, o10, o8, o7, o6, o9]
+ True
+
+ >>> results = list(cat.searchResults(color='blue', _sort_index='age', _limit=3))
+ >>> results == [o3, o10, o8]
+ True
+
+ >>> results = list(cat.searchResults(color='blue', _sort_index='age', _reverse=True))
+ >>> results == [o9, o6, o7, o8, o10, o3]
+ True
+
+ >>> results = list(cat.searchResults(color='blue', _sort_index='age', _reverse=True, _limit=4))
+ >>> results == [o9, o6, o7, o8]
+ True
+
The index example we looked at didn't provide document scores. Simple
indexes normally don't, but more complex indexes might give results
scores, according to how closely a document matches a query. Let's
Modified: zope.app.catalog/branches/nadako-sorting/src/zope/app/catalog/catalog.py
===================================================================
--- zope.app.catalog/trunk/src/zope/app/catalog/catalog.py 2008-12-27 21:06:10 UTC (rev 94387)
+++ zope.app.catalog/branches/nadako-sorting/src/zope/app/catalog/catalog.py 2008-12-27 22:06:40 UTC (rev 94395)
@@ -134,8 +134,23 @@
return result
def searchResults(self, **searchterms):
+ sort_index = searchterms.pop('_sort_index', None)
+ limit = searchterms.pop('_limit', None)
+ reverse = searchterms.pop('_reverse', False)
results = self.apply(searchterms)
if results is not None:
+ if sort_index is not None:
+ index = self[sort_index]
+ if not zope.index.interfaces.IIndexSort.providedBy(index):
+ raise ValueError('Index %s does not support sorting.' % sort_index)
+ results = list(index.sort(results, limit=limit, reverse=reverse))
+ else:
+ if reverse or limit:
+ results = list(results)
+ if reverse:
+ results.reverse()
+ if limit:
+ del results[limit:]
uidutil = component.getUtility(IIntIds)
results = ResultSet(results, uidutil)
return results
Modified: zope.app.catalog/branches/nadako-sorting/src/zope/app/catalog/interfaces.py
===================================================================
--- zope.app.catalog/trunk/src/zope/app/catalog/interfaces.py 2008-12-27 21:06:10 UTC (rev 94387)
+++ zope.app.catalog/branches/nadako-sorting/src/zope/app/catalog/interfaces.py 2008-12-27 22:06:40 UTC (rev 94395)
@@ -28,9 +28,26 @@
"""Provides Catalog Queries."""
def searchResults(**kw):
- """Search on the given indexes."""
+ """Search on the given indexes.
+
+ Keyword arguments dictionary keys
+ are index names and values are queries
+ for these indexes.
+
+ Keyword arguments has some special names,
+ used by the catalog itself:
+
+ * _sort_index - The name of index to sort
+ results with. This index must implement
+ zope.index.interfaces.IIndexSort.
+ * _limit - Limit result set by this number,
+ useful when used with sorting.
+ * _reverse - Reverse result set, also
+ useful with sorting.
+ """
+
class ICatalogEdit(zope.index.interfaces.IInjection):
"""Allows one to manipulate the Catalog information."""
More information about the Checkins
mailing list