def _mapreduce_keyfilter(self, index, keyfilter, sortby=None, limit=None):
        """
            Helper function to execute a map-reduce query using the given key filter
        """
        results = None
        log.debug("Riak query %r with key filter %r", index, keyfilter)

        mapred = RiakMapReduce(self.client)
        mapred.add_bucket(self._get_bucket(index))
        mapred.add_key_filters(keyfilter)
        # custom Riak.mapValuesJson() function that also adds the entry key to the data structure
        mapred.map("""
            function(value, keyData, arg) {
                if (value.not_found) {
                    return [value];
                }
                var _data, data = value["values"][0]["data"];
                if (Riak.getClassName(data) !== "Array") {
                    _data = JSON.parse(data);
                    _data["_key"] = value.key;
                    return [_data];
                }
                else {
                    return data
                }
            }
        """)

        if sortby is not None:
            comp = '<' if limit is not None and limit < 0 else '>'
            mapred.reduce_sort('function(a,b){ return (a.%s || 0) %s (b.%s || 0) ? 1 : 0; }' % (sortby, comp, sortby))

        if limit is not None:
            mapred.reduce_limit(abs(limit))

        try:
            results = mapred.run()

        except Exception, e:
            log.warning("Riak MapReduce exception: %s", str(e))
            results = None