Взятие суммы «столбец» в MongoDB - PullRequest
4 голосов
/ 16 января 2012

В MySQL я бы просто пошел "SELECT sum (pts) FROM table", чтобы получить сумму столбца pts в таблице. Однако я конвертирую это приложение в MongoDB и не могу найти простой способ получить сумму общего ключа «type» в моей коллекции. Я использую PHP, поэтому , пожалуйста, дайте код PHP для этой работы.

Вот мои данные:

{ "_id" : ObjectId("4f136dab5056f65b61000000"), "p_id" : "3", "g_id" : "1", "type" : "3" }
{ "_id" : ObjectId("4f136dad5056f65760000000"), "p_id" : "8", "g_id" : "1", "type" : "7" }
{ "_id" : ObjectId("4f136daf5056f65860000000"), "p_id" : "6", "g_id" : "1", "type" : "4" }
{ "_id" : ObjectId("4f136db15056f65460000000"), "p_id" : "27", "g_id" : "1", "type" : "2" }

Как получить сумму $, равную сумме ключа типа?

Ответы [ 7 ]

5 голосов
/ 02 октября 2012

Использование новой структуры агрегации MongoDB :

$result = $db->command(array(

    'aggregate' => 'COLLECTION_NAME',

    'pipeline'  => array(
        // Match:
        // We can skip this in case that we don't need to filter 
        // documents in order to perform the aggregation
        array('$match' => array(
            // Criteria to match against
        )),

        // Group:
        array('$group'  => array(
            // Groupby fields:
            '_id'       => "$fieldname1, $fieldname2, $or_empty, $etc",
            // Count:
            'count'     => array('$sum' => 1),
            // Sum:
            'type_sum'  => array('$sum' => '$type'),
        ))

        // Other aggregations may go here as it's really a PIPE :p

    ),
));
3 голосов
/ 16 января 2012

MongoDB не имеет ни одного простого запроса для выполнения суммы.

В MongoDB вам нужно будет выполнить специальную команду для этого. У вас есть три варианта.

  1. Использование Карта / Уменьшение . Это общий метод для суммирования, подсчета, усреднения и т. Д. В наборе данных. Это не тривиально, вам нужно прочитать документацию, чтобы понять, как это работает.
  2. Aggregation . Это специальная структура для выполнения заданий "мини-карта / сокращение". Пример group наглядно демонстрирует, как сделать «сумму по типу». Вам просто нужно преобразовать команду в PHP.
  3. Структура агрегации 1020 *. В настоящее время это только в нестабильной сборке (2.1.0). Это будет лучше, чем вариант № 2, но он будет работать только на 2,1 +.

... поэтому, пожалуйста, дайте код PHP, чтобы эта работа

Здесь нет простого фрагмента кода PHP, агрегирование - это действительно сложная тема в MongoDB.

Сначала вы должны выбрать один из методов (# 1, # 2, # 3), а затем вы должны решить, что вы планируете делать с выходными данными. Например, # 1 Map / Reduce, может создать новую коллекцию с агрегатами или может возвращать значения в строке, но могут быть возвращены только 10k значений. Вариант № 2 будет работать в последовательном режиме и будет очень медленным на защищенных серверах. Вариант № 3 все еще находится в "бета-версии" и в конечном итоге заменит # 2.

В любом случае, перед выбором плана атаки все параметры потребуют дальнейшего чтения.

2 голосов
/ 25 мая 2012

Это можно сделать с помощью следующих функций уменьшения карты:

var map = function () {
    emit("total", {sum:this.type}) 
    }

var reduce = function (key, values) {
    var result = {sum:0};
    values.forEach(function (value) {result.sum += value.type;});
    return result;
    }

db.table.mapReduce(map, reduce, {out : "type_totals"})

или в php:

$db->table->mapReduce( array( 
   'map' =>
   'function () {
      emit("total", {sum:this.type});
 }' 
,'reduce' =>
   'function (key, values) {
      var result = {sum:0};
      values.forEach(function (value) {result.sum += value.type;});
      return result;
     }'));
1 голос
/ 15 января 2013
$mongo = new Mongo();

$map = new MongoCode("function() { emit('total', this.type); }");
$reduce = new MongoCode("function(k, vals) {
    var sum = 0;
    for(i in vals) {
        sum += vals[i];
    }

    return sum;
}");

$sumtotal = $mongo->db->command(array(
    'mapreduce' => 'tableName',
    'map' => $map,
    'reduce' => $reduce,
    // 'query' => array('col' => 'value'),
    'out' => array('merge' => 'tableName_sum')
));

$result = $mongo->db->selectCollection($sumtotal['result'])->findOne();
$sum = $result['value'];
1 голос
/ 17 января 2012

Другое решение заключается в создании в базе данных сценария, который будет суммировать требуемые данные и возвращать ваш результат примерно так:

Сценарий

function sum() {
   var sum = 0;
   for (var query = db.collection.find({}, {type: 1, _id:0}); query.hasNext();) {
      sum += query.next();
   }
   return sum;
}

PHP

В php после установки соединения с БД это будет что-то вроде:

$toexec = 'function(x, y) { return sum() }';
$response = $database->execute($toexec, array());

Посмотрите этот урок, чтобы узнать больше о скриптинге на монго с php.

http://pointbeing.net/weblog/2010/08/getting-started-with-stored-procedures-in-mongodb.html

0 голосов
/ 11 апреля 2017
Try:
$m = new MongoClient();
$con = $m->selectDB("dbName")->selectCollection("collectionName");
$cond = array(
    array(
        '$group' => array(
            '_id' => null,
           'total' => array('$sum' => '$type'),
        ),
    )
);

$out = $con->aggregate($cond);
print_r($out);

Подробнее нажмите здесь

0 голосов
/ 15 июля 2015

Другие ответы уже дали много источников. Просто отвечаю на заданный вопрос:

db.YOUR_COLLECTTION.aggregate([ { 
    $group: { 
        _id: null, 
        total: { 
            $sum: "$type" 
        } 
    } 
} ] )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...