Mongo mapreduce — используйте $ dateToString на этапе отображения

У меня есть простая коллекция элементов со следующей структурой:

{
_id: MongoId
pvs: int
day: IsoDate()
uid: int
}

Я хотел бы использовать MapReduce рассчитывать количество просмотров страниц для данного пользователя, сгруппированных по определенному диапазону дат (день / неделя / месяц, дата format совместимый).

Я застрял, как переформатировать IsoDate в функции карты с помощью $dateToString перед излучением, поэтому он выделяет формат, который я хочу, как %Y-%m-%d или же %Y-%m или же %Y-%m-%U,
Когда я звоню, я получаю не переформатированную дату, а возражаю format а также date поля.

Пример:

function(){
emit(
{'$dateToString': {'format': "%Y-%m-%d", 'date': this.day}},
this.pvs
)}

вернусь

{
"pvs" : 5
"$dateToString" : {
"format" : "%Y-%m-%d",
"date" : ISODate("2016-07-13T08:27:29.000Z")
}
}

Я хочу получить это взамен:

{
"pvs": 5,
"day": "2016-07-13"}

1

Решение

Если вы используете mapReduce, вам нужно создать собственную пользовательскую функцию, которая форматирует дату и вызвать ее в вашей функции карты:

dateToString = function(date){
return date.getFullYear() + '-' (date.getMonth() + 1) + '-' + date.getDate();
}

map = function() {
emit(dateToString(this.day), this.pvs);
}

Лучше с платформой агрегации, которая запускается «внутри» MongoDB в ее коде C ++, следовательно, более эффективна, чем mapReduce, которая работает в среде V8 / spidermonkey (в зависимости от вашей версии) на встроенной консоли JS:

db.collectionName.aggregate([
{ "$match": { "uid": userId } },
{
"$project": {
"formattedDate": {
"$dateToString": { "format": "%Y-%m-%d", "date": "$day" }
},
"pvs": 1
}
},
{
"$group": {
"_id": "$formattedDate",
"pvs": { "$sum": "$pvs" }
}
}
])

который в доктрине Монго Одм вы можете запустить свой конвейер, используя command функционировать как:

$connection = $this->get('doctrine_mongodb')->getConnection();
$mongo = $connection->getMongo();
if (!$mongo) {
$connection->connect();
$mongo = $connection->getMongo();
}
$db = $mongo->selectDB('test_database');
$aggregate_results = $db ->command(array(
"aggregate" => "collectionName",
"pipeline" => array(
array("$match" => array("uid"=>  userId )),
array(
"$project" => array(
"formattedDate" => array(
"$dateToString" => array("format" => "%Y-%m-%d", "date"=>  "$day")
),
"pvs" =>  1
)
),
array(
"$group" => array(
"_id" => "$formattedDate",
"pvs" => array("$sum" => "$pvs")
)
)
)
));
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]