Added support for null / zero / false values in item_frequencies
refs /MongoEngine/mongoengine#40
This commit is contained in:
@@ -1718,10 +1718,11 @@ class QuerySet(object):
|
||||
def _item_frequencies_map_reduce(self, field, normalize=False):
|
||||
map_func = """
|
||||
function() {
|
||||
path = '{{~%(field)s}}'.split('.');
|
||||
field = this;
|
||||
var path = '{{~%(field)s}}'.split('.');
|
||||
var field = this;
|
||||
|
||||
for (p in path) {
|
||||
if (field)
|
||||
if (typeof field != 'undefined')
|
||||
field = field[path[p]];
|
||||
else
|
||||
break;
|
||||
@@ -1730,7 +1731,7 @@ class QuerySet(object):
|
||||
field.forEach(function(item) {
|
||||
emit(item, 1);
|
||||
});
|
||||
} else if (field) {
|
||||
} else if (typeof field != 'undefined') {
|
||||
emit(field, 1);
|
||||
} else {
|
||||
emit(null, 1);
|
||||
@@ -1754,12 +1755,12 @@ class QuerySet(object):
|
||||
if isinstance(key, float):
|
||||
if int(key) == key:
|
||||
key = int(key)
|
||||
key = str(key)
|
||||
frequencies[key] = f.value
|
||||
frequencies[key] = int(f.value)
|
||||
|
||||
if normalize:
|
||||
count = sum(frequencies.values())
|
||||
frequencies = dict([(k, v / count) for k, v in frequencies.items()])
|
||||
frequencies = dict([(k, float(v) / count)
|
||||
for k, v in frequencies.items()])
|
||||
|
||||
return frequencies
|
||||
|
||||
@@ -1767,31 +1768,28 @@ class QuerySet(object):
|
||||
"""Uses exec_js to execute"""
|
||||
freq_func = """
|
||||
function(path) {
|
||||
path = path.split('.');
|
||||
var path = path.split('.');
|
||||
|
||||
if (options.normalize) {
|
||||
var total = 0.0;
|
||||
db[collection].find(query).forEach(function(doc) {
|
||||
field = doc;
|
||||
for (p in path) {
|
||||
if (field)
|
||||
field = field[path[p]];
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (field && field.constructor == Array) {
|
||||
total += field.length;
|
||||
} else {
|
||||
total++;
|
||||
}
|
||||
});
|
||||
}
|
||||
var total = 0.0;
|
||||
db[collection].find(query).forEach(function(doc) {
|
||||
var field = doc;
|
||||
for (p in path) {
|
||||
if (field)
|
||||
field = field[path[p]];
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (field && field.constructor == Array) {
|
||||
total += field.length;
|
||||
} else {
|
||||
total++;
|
||||
}
|
||||
});
|
||||
|
||||
var frequencies = {};
|
||||
var types = {};
|
||||
var inc = 1.0;
|
||||
if (options.normalize) {
|
||||
inc /= total;
|
||||
}
|
||||
|
||||
db[collection].find(query).forEach(function(doc) {
|
||||
field = doc;
|
||||
for (p in path) {
|
||||
@@ -1806,17 +1804,28 @@ class QuerySet(object):
|
||||
});
|
||||
} else {
|
||||
var item = field;
|
||||
types[item] = item;
|
||||
frequencies[item] = inc + (isNaN(frequencies[item]) ? 0: frequencies[item]);
|
||||
}
|
||||
});
|
||||
return frequencies;
|
||||
return [total, frequencies, types];
|
||||
}
|
||||
"""
|
||||
data = self.exec_js(freq_func, field, normalize=normalize)
|
||||
if 'undefined' in data:
|
||||
data[None] = data['undefined']
|
||||
del(data['undefined'])
|
||||
return data
|
||||
total, data, types = self.exec_js(freq_func, field)
|
||||
values = dict([(types.get(k), int(v)) for k, v in data.iteritems()])
|
||||
|
||||
if normalize:
|
||||
values = dict([(k, float(v) / total) for k, v in values.items()])
|
||||
|
||||
frequencies = {}
|
||||
for k, v in values.iteritems():
|
||||
if isinstance(k, float):
|
||||
if int(k) == k:
|
||||
k = int(k)
|
||||
|
||||
frequencies[k] = v
|
||||
|
||||
return frequencies
|
||||
|
||||
def __repr__(self):
|
||||
"""Provides the string representation of the QuerySet
|
||||
|
Reference in New Issue
Block a user