Рубрики
Без рубрики

MongoDB 2.6 стоит $

Автор оригинала: Vlad Mihalcea.

Вступление

MongoDB быстро развивается. В версии 2.2 была представлена структура агрегации в качестве альтернативы модели Map-Reduce запросов. Создание агрегированных отчетов является постоянным требованием для корпоративных систем, и в этом отношении MongoDB работает. Если вы новичок в этом, вы, возможно, захотите проверить это введение в структуру агрегации или настройка производительности и моделирование данных руководства.

Давайте повторно используем модель данных, которую я впервые представил, демонстрируя невероятно быстрые возможности вставки MongoDB:

{
        "_id" : ObjectId("5298a5a03b3f4220588fe57c"),
        "created_on" : ISODate("2012-04-22T01:09:53Z"),
        "value" : 0.1647851116706831
}

Улучшения агрегации MongoDB 2.6

В версии 2.4, если я выполню следующий запрос агрегации:

db.randomData.aggregate( [ 
{ 
    $match: { 
        "created_on" : { 
            $gte : new Date(Date.UTC(2012, 0, 1)), 
            $lte : new Date(Date.UTC(2012, 0, 10)) 
        } 
    } 
},  
{ 
    $group: {
        _id : {
            "minute" : {
                $minute : "$created_on"
            } 
        },  
        "values": { 
            $addToSet: "$value" 
        } 
    } 
}]);

Я достиг ограничения на результат агрегации 16 МБ:

{
    "errmsg" : "exception: aggregation result exceeds maximum document size (16MB)",
    "code" : 16389,
    "ok" : 0
}

Документы MongoDB ограничены 16 МБ , и до версии 2.6 результатом агрегирования был документ BSON. Версия 2.6 заменила его курсором вместо этого.

Выполнение того же запроса на 2.6 дает следующий результат:

db.randomData.aggregate( [ 
{ 
    $match: { 
        "created_on" : { 
            $gte : new Date(Date.UTC(2012, 0, 1)), 
            $lte : new Date(Date.UTC(2012, 0, 10)) 
        } 
    } 
},  
{ 
    $group: {
        _id : {
            "minute" : {
                $minute : "$created_on"
            } 
        },  
        "values": { 
            $addToSet: "$value" 
        } 
    } 
}])
.objsLeftInBatch();
14

Я использовал метод objsLeftInBatch на основе курсора для проверки типа результата агрегирования, и ограничение в 16 МБ больше не применяется к общему результату. Внутренние результаты курсора являются обычными документами BSON, поэтому они по-прежнему ограничены 16 МБ, но это намного более управляемо, чем предыдущий общий лимит результатов.

В версии 2.6 также рассматриваются ограничения памяти агрегации . Полное сканирование коллекции, например:

db.randomData.aggregate( [   
{ 
    $group: {
        _id : {
            "minute" : {
                $minute : "$created_on"
            } 
        },  
        "values": { 
            $addToSet: "$value" 
        } 
    } 
}])
.objsLeftInBatch();

может привести к следующей ошибке:

{
    "errmsg" : "exception: Exceeded memory limit for $group, but didn't allow external sort. Pass allowDiskUse:true to opt in.",
    "code" : 16945,
    "ok" : 0
}

Итак, теперь мы можем выполнять большие операции сортировки с помощью параметра allowDiskUse:

db.randomData.aggregate( [   
{ 
    $group: {
        _id : {
            "minute" : {
                $minute : "$created_on"
            } 
        },  
        "values": { 
            $addToSet: "$value" 
        } 
    } 
}]
, 
{ 
    allowDiskUse : true 
})
.objsLeftInBatch();

Версия 2.6 позволяет нам сохранить результат агрегирования в другой коллекции, используя недавно добавленный этап $out .

db.randomData.aggregate( [ 
{ 
    $match: { 
        "created_on" : { 
            $gte : new Date(Date.UTC(2012, 0, 1)), 
            $lte : new Date(Date.UTC(2012, 0, 10)) 
        } 
    } 
},  
{ 
    $group: {
        _id : {
            "minute" : {
                $minute : "$created_on"
            } 
        },  
        "values": { 
            $addToSet: "$value" 
        } 
    } 
},
{ 
    $out : "randomAggregates" 
}
]);
db.randomAggregates.count();
60

Были добавлены новые операторы, такие как let , карта , значки , и это лишь некоторые из них.

В следующем примере к информации о времени каждой конкретной записи события будет добавлено AM или PM.

var dataSet = db.randomData.aggregate( [ 
{ 
    $match: { 
        "created_on" : { 
            $gte : new Date(Date.UTC(2012, 0, 1)), 
            $lte : new Date(Date.UTC(2012, 0, 2)) 
        } 
    } 
},  
{ 
    $project: { 
        "clock" : { 
            $let: {
                vars: {
                    "hour": { 
                        $substr: ["$created_on", 11, -1]
                    },              
                    "am_pm": { $cond: { if: { $lt: [ {$hour : "$created_on" }, 12 ] } , then: 'AM',else: 'PM'} }
                },
                in: { $concat: [ "$$hour", " ", "$$am_pm"] }              
            }           
        }   
    } 
}, 
{
    $limit : 10
}
]);
dataSet.forEach(function(document)  {
    printjson(document);
});

В результате чего:

"clock" : "16:07:14 PM"
"clock" : "22:14:42 PM"
"clock" : "21:46:12 PM"
"clock" : "03:35:00 AM"
"clock" : "04:14:20 AM"
"clock" : "03:41:39 AM"
"clock" : "17:08:35 PM"
"clock" : "18:44:02 PM"
"clock" : "19:36:07 PM"
"clock" : "07:37:55 AM"

Вывод

Версия MongoDB 2.6 поставляется с множеством других улучшений , таких как массовые операции или пересечение индексов . MongoDB постоянно развивается, предлагая жизнеспособную альтернативу для хранения документов на основе. При таких темпах развития неудивительно, что он был назван базой данных 2013 года .