From 2e3a3ace848d25c8c7cbee4d7da671a10375abbb Mon Sep 17 00:00:00 2001 From: Elena ``of Valhalla'' Grandi Date: Fri, 30 Oct 2020 13:59:54 +0100 Subject: Support sorting search results --- CHANGELOG.rst | 1 + lesana/collection.py | 17 ++++++++++++++++- tests/test_collection.py | 21 +++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) 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): -- cgit v1.2.3