Исходные типы прекрасны, когда они выражают то, что вы хотите выразить.
Например, функция десериализации может возвращать List
, но она не знает тип элемента списка. Таким образом, List
является подходящим типом возврата.
Я столкнулся с такой же ситуацией. Я смог выполнить это через запрос и прогнозы Монго. см. Mongo Query
Но это кажется неудобным, и я не знаю, почему он даже работает, поскольку мои аргументы вызова
blockquote>emit
в моем картографе не эквивалентны возвращаемому аргументу моегоreducer
.Они эквивалентны. Функция уменьшения принимает в массив значения
T
и должна возвращать одно значение в том же форматеT
. ФорматT
определяется вашей функцией отображения. Функция сокращения просто возвращает первый элемент в массиве значений, который всегда будет иметь типT
. Вот почему он работает:)Кажется, что вы на правильном пути. Я экспериментировал, и, похоже, вы не можете сделать
db.collection.save()
из функции карты, но вы можете сделать это из функции уменьшения. Ваша функция карты должна просто создать необходимый формат документа:function map() { emit(this._id, { _id: this.id, heading: this.title, body: this.content }); }
Функция карты повторно использует идентификатор исходного документа. Это должно предотвратить любые шаги повторного уменьшения, поскольку никакие значения не будут использовать один и тот же ключ.
Функция уменьшения может просто вернуть
null
. Но, кроме того, вы можете записать значение в отдельную коллекцию.function reduce(key, values) { db.result.save(values[0]); return null; }
Теперь
db.result
должен содержать преобразованные документы без каких-либо дополнительных шумов, уменьшающих размер карты, которые вы имели бы во временной коллекции. Я на самом деле не тестировал это на больших объемах данных, но этот подход должен использовать преимущества параллельного выполнения функций уменьшения карты.
db.coll.mapReduce(myMapperFunc, null, {'out': 'output'})
. Я думаю, что сокращение позволяет пакетно сохранять / вставлять весь набор элементов; Я думаю, что узким местом здесь является save()
, называемый в каждом сокращении.
– chbrown
28 August 2010 в 19:24
save()
выполняется дважды для каждого документа; стандартное сокращение - сохранить во временную коллекцию и явное сохранение в отдельную коллекцию. Любопытно, действительно ли это решение быстрее, чем с помощью одного курсора?
– Niels van der Rest
28 August 2010 в 20:49
При использовании map / reduce вы всегда будете иметь
{ "value" : { <reduced data> } }
. Чтобы удалить клавишу value
, вам нужно будет использовать функцию finalize
.
Ниже вы можете скопировать данные из одной коллекции в другую:
map = function() { emit(this._id, this ); }
reduce = function(key, values) { return values[0]; }
finalize = function(key, value) { db.collection_2.insert(value); }
Тогда, когда вы будете работать как обычно:
db.collection_1.mapReduce(map, reduce, { finalize: finalize });
Когда вы получили доступ к оболочке mongo, он принимает некоторые команды Javascript, а затем он проще:
map = function(item){
db.result.insert(item);
}
db.collection.find().forEach(map);
Только карта без сокращения похожа на копирование коллекции: http://www.mongodb.org/display/DOCS/Developer+FAQ#DeveloperFAQ-HowdoIcopyallobjectsfromonedatabasecollectiontoanother%3F