'This method returns for a specific query `flt` a list of
dictionary objects whose keys are `id` and `mean`; the value
for `id` is a backend-dependant and uniquely identifies a
record, and the value for `mean` is given by:
(number of open ports) * sum(port number for each open port)
This MongoDB specific implementation uses the aggregation
framework to have most of the work done within the DB
server.
However, it is broken for now as it does not handle hosts with
no open port but with a ports attribute.
See
* https://stackoverflow.com/questions/23636175
* https://stackoverflow.com/questions/22114748'

def get_mean_open_ports(self, flt, archive=False):

    aggr = []
    if flt:
        aggr += [{'$match': flt}]
    aggr += [{'$project': {'ports.port': 1, 'ports.state_state': 1}}, {'$project': {'ports': {'$ifNull': ['$ports', []]}}}, {'$redact': {'$cond': {'if': {'$eq': [{'$ifNull': ['$ports', None]}, None]}, 'then': {'$cond': {'if': {'$eq': ['$state_state', 'open']}, 'then': '$$KEEP', 'else': '$$PRUNE'}}, 'else': '$$DESCEND'}}}, {'$project': {'ports': {'$cond': [{'$eq': ['$ports', []]}, [0], '$ports.port']}}}, {'$unwind': '$ports'}, {'$group': {'_id': '$_id', 'count': {'$sum': 1}, 'ports': {'$sum': '$ports'}}}, {'$project': {'_id': 0, 'id': '$_id', 'mean': {'$multiply': ['$count', '$ports']}}}]
    return self.db[(self.colname_oldhosts if archive else self.colname_hosts)].aggregate(aggr, cursor={})
