Обратите внимание, что есть случаи, когда вы определили свой собственный пользовательский класс и хотите сохранить атрибуты, тогда вы должны использовать copy.copy()
или copy.deepcopy()
, а не альтернативы, например, в Python 3:
import copy
class MyList(list):
pass
lst = MyList([1,2,3])
lst.name = 'custom list'
d = {
'original': lst,
'slicecopy' : lst[:],
'lstcopy' : lst.copy(),
'copycopy': copy.copy(lst),
'deepcopy': copy.deepcopy(lst)
}
for k,v in d.items():
print('lst: {}'.format(k), end=', ')
try:
name = v.name
except AttributeError:
name = 'NA'
print('name: {}'.format(name))
Выходы:
lst: original, name: custom list
lst: slicecopy, name: NA
lst: lstcopy, name: NA
lst: copycopy, name: custom list
lst: deepcopy, name: custom list
Теперь есть агенты преобразования $ toInt в агрегации, вы можете проверить: https://jira.mongodb.org/browse/SERVER-11400
Один из способов, о котором я могу думать, - использовать javascript оболочки mongo для изменения документа, добавив новое числовое поле, valuessnumber (числовое преобразование существующего поля «значение строки») в существующий документ или в новый документ , Затем используйте это числовое поле для дальнейших вычислений.
db.numbertest.find().forEach(function(doc) {
doc.valueasnumber = new NumberInt(doc.value);
db.numbertest.save(doc);
});
Использование поля valuesnumber для числового вычисления
db.numbertest.aggregate([{$group :
{_id : null,
"score" : {$avg : "$valueasnumber"}
}
}]);
Основная операция - преобразовать значение из строки в число, которое невозможно обработать в aggregate pipeline operation
в настоящее время. mapReduce - альтернатива, как показано ниже.
db.c.mapReduce(function() {
emit( this.groupId, {score: Number(this.value), count: 1} );
}, function(key, values) {
var score = 0, count = 0;
for (var i = 0; i < values.length; i++) {
score += values[i].score;
count += values[i].count;
}
return {score: score, count: count};
}, {finalize: function(key, value) {
return {score: value.score / value.count};
}, out: {inline: 1}});