summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.rst1
-rw-r--r--lesana/collection.py17
-rw-r--r--tests/test_collection.py21
3 files changed, 38 insertions, 1 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index c84635f..6cbb043 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -8,6 +8,7 @@ Unreleased
* Improved round trip loading of data results in less spurious changes
when editing entries.
* More documentation and examples.
+* Added support for sorting search results.
0.6.2
=====
diff --git a/lesana/collection.py b/lesana/collection.py
index 7a4ff11..af3977d 100644
--- a/lesana/collection.py
+++ b/lesana/collection.py
@@ -312,7 +312,7 @@ class Collection(object):
)
return cache
- def start_search(self, querystring):
+ def start_search(self, querystring, sort_by=None):
"""
Prepare a search for querystring.
"""
@@ -329,6 +329,21 @@ class Collection(object):
self._enquire = xapian.Enquire(cache)
self._enquire.set_query(query)
+ if sort_by:
+ keymaker = xapian.MultiValueKeyMaker()
+ for k in sort_by:
+ if k.startswith('+'):
+ reverse = False
+ slot = self.fields[k[1:]].value_index
+ elif k.startswith('-'):
+ reverse = True
+ slot = self.fields[k[1:]].value_index
+ else:
+ reverse = False
+ slot = self.fields[k].value_index
+ keymaker.add_value(slot, reverse)
+ self._enquire.set_sort_by_key_then_relevance(keymaker, False)
+
def get_search_results(self, offset=0, pagesize=12):
if not self._enquire:
return
diff --git a/tests/test_collection.py b/tests/test_collection.py
index f3e06da..8d4cf88 100644
--- a/tests/test_collection.py
+++ b/tests/test_collection.py
@@ -332,6 +332,27 @@ class testComplexCollection(unittest.TestCase):
with open(fname, 'r') as fp:
self.assertEqual(e.yaml_data, fp.read())
+ def test_sorted_search(self):
+ # search in ascending order
+ self.collection.start_search('Amount', sort_by=['amount'])
+ res = self.collection.get_search_results()
+ matches = list(res)
+ self.assertEqual(len(matches), 4)
+ self.assertEqual(matches[0].data['amount'], 2)
+ self.assertEqual(matches[1].data['amount'], 10)
+ self.assertEqual(matches[2].data['amount'], 15)
+ self.assertEqual(matches[3].data['amount'], 20)
+
+ # and in descending order
+ self.collection.start_search('Amount', sort_by=['-amount'])
+ res = self.collection.get_search_results()
+ matches = list(res)
+ self.assertEqual(len(matches), 4)
+ self.assertEqual(matches[0].data['amount'], 20)
+ self.assertEqual(matches[1].data['amount'], 15)
+ self.assertEqual(matches[2].data['amount'], 10)
+ self.assertEqual(matches[3].data['amount'], 2)
+
class testCollectionWithErrors(unittest.TestCase):
def setUp(self):