Я использовал группировку на mongoDB через PHP, чтобы получить максимальную дату своих товаров.
Поскольку у меня слишком много элементов (более 10 000), я прочитал, что должен использовать MapReduce.
Вот моя последняя групповая функция:
$keys = array('ItemDate'=> true);
$initial = array('myLastDate' => 0);
$reduce = "function(obj, prev) {
if (myLastDate < obj.ItemDate) {
myLastDate = ItemDate;
}
}";
$conds = array( 'ItemID' => (int) $id );
$results = $db->items->group($keys, $initial, $reduce,
array('condition'=> $conds ) );
Я пробовал что-то, но, кажется, не работает …
$map = new MongoCode("function() {
emit(this.ItemID,this.ItemDate);
}");
$reduce = new MongoCode("function(obj, prev) {
if(prev.myLastDate < obj.ItemDate) {
prev.myLastDate = obj.ItemDate;
}
}");
$items = $db->command(array(
"mapreduce" => "items",
"map" => $map,
"reduce" => $reduce,
"query" => array("ItemID" => $id);
$results = $db->selectCollection($items['result'])->find();
Можете ли вы помочь?
Вам не нужно использовать карту / уменьшить для этого. При условии, что ваше поле даты содержит ISODate, простой запрос делает свое дело:
db.yourColl.find({},{_id:0,ItemDate:1}).sort({ItemDate:-1}).limit(1)
Для того чтобы этот запрос был выполнен эффективно, вам нужно установить индекс на ItemDate
db.yourColl.createIndex({ItemDate:-1})
Давайте разберем запрос. db.yourColl
…
.find({}
Запрос по умолчанию,{_id:0,ItemDate:1}
Мы хотим только ItemDate
быть возвращенным. Это называется проекция..sort({ItemDate:-1})
Возвращенные документы должны быть отсортированы в порядке убывания на ItemDate, чтобы документ с самой новой датой был возвращен первым..limit(1)
И так как мы хотим только самое новое, мы ограничиваем набор результатов для него.Мы создаем индекс в порядке убывания, так как вы собираетесь его использовать. Однако если вам нужно изменить запрос по умолчанию на что-то другое, создаваемый вами индекс должен включать все поля, которые вы проверяете в запросе, в точном порядке.
Других решений пока нет …