views:

21

answers:

1

Hi,

I'm using djapian as my search backend, and I'm looking to search for a range of values. For example:

query = 'comments:(0..10)'
Post.indexer.search(query)

would search for Posts with between 0 and 10 comments. I cannot find a way to do this in djapian, though I have found this issue, and patch to implement some kind of date range searching. I also found this page from the xapian official docs describing some kind of range query. However, I lack the knowledge to either formulate my own raw xapian query, and/or feed a raw xapian query into djapian. So help me SO, how can I query a djapian index for a range of int values.

Thanks,

Laurie

A: 

Ok, I worked it out. I'll leave the answer here for posterity.

The first thing to do is to attach a NumberValueRangeProcessor to the QueryParser. You can do this by extending the djapian Indexer._get_query_parser. Note the leading underscore. Below is a code snippet showing how I did it.

from djapian import Indexer
from xapian import NumberValueRangeProcessor

class RangeIndexer(Indexer)
    def _get_query_parser(self, *args, **kwargs):
        query_parser = Indexer._get_query_parser(self, *args, **kwargs)
        valno = self.free_values_start_number + 0
        nvrp = NumberValueRangeProcessor(valno, 'value_range:', True)
        query_parser.add_valuerangeprocessor(nvrp)
        return query_parser

Lines to note:

valno = self.free_values_start_number + 0

The self.free_values_start_number is an int, and used as the value no, it is the index of the first column where fields start being defined. I added 0 to this, to indicate that you should add the index of the field you want the range search to be for.

nvrp = NumberValueRangeProcessor(valno, 'value_range:', True)

We send valno to tell the processor what field to deal with. The 'value_range:' indicates the prefix for the processor, so we can search by saying 'value_range:(0..100)'. The True simply indicates that the 'value_range:' should be treated as a prefix not a suffix.

query_parser.add_valuerangeprocessor(nvrp)

This simply adds the NumberValueRangeProcessor to the QueryParser.

Hope that helps anyone who has any problems with this matter. Note that you will need to add a new NumberValueRangeProcessor for each field you want to be able to range search.

Blue Peppers