Я импортировал БД из CSV с информацией о:
- страна
- регион
- 1008 * товарный *
- цена
- дата
(Это CSV: https://www.kaggle.com/jboysen/global-food-prices)
строки в CSV упорядочены следующим образом:
- страна 1, регион 1.1, товар X, цена, датаA
- страна 1, регион 1.1, товар X, цена, дата B
- страна 1, регион 1.1, товар Y, цена, датаA
- страна 1, регион 1.1, товар Y, цена, дата B
- ...
- страна 1, регион 1.2, товар X, цена, датаA
- страна 1, регион 1.2, товар X, цена, дата B
- страна 1, регион 1.2, товар Y, цена, датаA
- страна 1, регион 1.2, товар Y, цена, дата B
- ...
- страна 2, регион 2.1, товар X, цена, датаA
- ...
Мне нужно показать для каждой страны, для каждого продукта самую большую цену.
Я написал:
1) карта с указанием ключевой страны + цена товара и стоимости
var map = function() {
emit({country: this.country_name, commodity: this.commodity_name}, {price: this.price});
};
2) снижение, которое сканирует цены, связанные с ключом, и проверяет, какая цена самая высокая
var reduce = function(key, values) {
var maxPrice = 0.0;
values.forEach(function(doc) {
var thisPrice = parseFloat(doc.price);
if( typeof doc.price != "undefined") {
if (thisPrice > maxPrice) {
maxPrice = thisPrice;
}
}
});
return {max_price: maxPrice};
};
3) Я отправляю вывод карты уменьшить в коллекцию "mr"
db.prices.mapReduce(map, reduce, {out: "mr"});
ПРОБЛЕМА:
Например, если я открою csv и вручную закажу:
- страна (в порядке возрастания)
- товар (в порядке возрастания)
- цена (в порядке убывания)
Я могу проверить, что (для примера) в Афганистане самая высокая цена на товарный хлеб - 65,25
.
Когда я проверяю M-R, он выдает 0 для максимальной цены на хлеб в Афганистане.
ЧТО ПРОИСХОДИТ:
В CSV есть 10 регионов, в которых Хлеб зарегистрирован для Афганистана.
Я добавил в последней строке уменьшения:
print("reduce with key: " + key.country + ", " + key.commodity + "; max price: " + maxPrice);
Теоретически, если я ищу в журнале mongodb, я должен найти только ОДИН вход с "уменьшить с помощью ключа: Афганистан, Хлеб; максимальная цена: ???".
Вместо этого я вижу десять линий (одинаковые номера регионов), каждая из которых имеет свою максимальную цену.
Последний имеет "максимальную цену 0".
МОЙ ГИПОТЕЗ:
Похоже, что после emit, когда вызываетсяужение, вместо поиска ВСЕХ пар k-v с одним и тем же ключом, он рассматривает подгруппы, находящиеся в расплывчатости.
Итак, вспоминая мой начальный пример структуры csv:
- до тех пор, пока при сканировании с уменьшением не выдаст выходные данные, относящиеся к "афганисте, регион 1, хлеб", он не уменьшит их
- затем сокращаются результаты, связанные с "Афганистаном, регион 1, товаромX"
- затем он еще раз сокращает результаты, относящиеся к «Афганистану, регион 2, хлеб» (вместо сокращения ВСЕХ пар k-v с Афганистаном + хлеб за одно сокращение)
Нужно ли выполнять повторное сокращение, чтобы работать на всех работах с частичным сокращением?