Принимая сумму «столбца» в MongoDB

В MySQL я бы просто пошел «SELECT sum (pts) FROM table», чтобы получить сумму столбца pts в таблице. Тем не менее, я конвертирую это приложение в MongoDB и не могу найти простой способ получить сумму общего «типа» в моей коллекции. Я использую 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" } 

Как я могу получить $ sum, чтобы равняться сумме ключа «type»?

Используя новую структуру агрегации 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 ), )); 

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

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

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

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

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

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

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

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

 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; }')); 

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

Сценарий

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

PHP

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

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

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

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

 $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']; 

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

 db.YOUR_COLLECTTION.aggregate([ { $group: { _id: null, total: { $sum: "$type" } } } ] ) 
 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); 

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