Агрегация возрастной группы Монго

Пожалуйста, рассмотрите сборник ниже

$people->insert(array("user_id" => "1", "day" => "Monday", 'age' => 18)); $people->insert(array("user_id" => "3", "day" => "Monday", 'age' => 24)); $people->insert(array("user_id" => "1", "day" => "Monday", 'age' => 18)); $people->insert(array("user_id" => "1", "day" => "Monday", 'age' => 18)); $people->insert(array("user_id" => "2", "day" => "Monday", 'age' => 25)); $people->insert(array("user_id" => "4", "day" => "Monday", 'age' => 33)); $people->insert(array("user_id" => "1", "day" => "Tuesday", 'age' => 18)); $people->insert(array("user_id" => "2", "day" => "Tuesday", 'age' => 25)); $people->insert(array("user_id" => "1", "day" => "Wednesday", 'age' => 18)); $people->insert(array("user_id" => "2", "day" => "Thursday", 'age' => 25)); $people->insert(array("user_id" => "1", "day" => "Friday", 'age' => 18)); 

Может ли кто-нибудь помочь мне получить количество отдельных пользователей в возрастной группе? Например, для схемы выше я хотел бы получить

  Age 0-17 = 0, Age 18-25 = 3, Age 26-32 = 0 Age > 32 = 1 

Я попытался использовать оператор $ cond, но не смог заставить его работать. Каждый раз, когда я пытаюсь запустить или изменить его, я получаю одну из двух ошибок:

  1. Оператору $ cond требуется 3 операнда или
  2. Объект спецификации этапа трубопровода должен содержать ровно одно поле.

Мой запрос рев, любая помощь очень ценится. Заранее спасибо,

  $query = array( $project' => array( ageGroup' => array( array('$cond'=> array('$user_data.age' => array('$lt' => 18), "age_0_17", array('$cond'=> array('$user_data.age' => array('$lte' => 25), "age_18_25", array('$cond'=> array('$user_data.age' => array('$lte' => 32), "age_26_32", "age_Above_32"))))) ) ), ), array( '$group' => array( '_id' => '$ageGroup', 'count' => array('$sum' => 1), ) )); 

Ответ @Neil Lunn на 90% прав, он не дал мне желаемого результата, но привел меня туда.

С запросом Neil я получаю:

 age_Above_32 = 1 and age_18_25 = 10 

Результат для отдельного счетчика user_id должен быть

 age_Above_32 = 1 and age_18_25 = 3 

Чтобы получить то, что мне просто пришлось немного подправить запрос Нила. Окончательный запрос приведен ниже.

 $query2 = array( array( '$group' => array( '_id' => array( 'ageGroup' => array( '$cond' => array( array('$lt' => array( '$age', 18 )), 'age_0_17', array( '$cond' => array( array( '$lte' => array( '$age', 25 )), 'age_18_25', array( '$cond' => array( array( '$lte' => array ( '$age', 32 )), 'age_26_32', 'age_Above_32' ) ) ) ) ) ), 'user_id' =>'$user_id' ) ) ), array( '$group' => array( '_id' => '$_id.ageGroup', 'count' => array('$sum' => 1) )) ); 

Solutions Collecting From Web of "Агрегация возрастной группы Монго"

Вы были в правильном месте, но поскольку $cond требует три аргумента (оценка, истинный результат и ложный результат), вам нужно «вложить» эти операции, которые каждый последующий $cond является false условием. Таким образом, ваш синтаксис здесь немного.

Вы также можете сделать это только в группе $group чтобы избежать прохождения всей коллекции с помощью отдельного $project . Основываясь на структуре документа, которую вы приводите в качестве примера, вы бы создали следующее:

 $pipeline = array( array( '$group' => array( '_id' => array( '$cond' => array( array('$lt' => array( '$age', 18 )), 'age_0_17', array( '$cond' => array( array( '$lte' => array( '$age', 25 )), 'age_18_25', array( '$cond' => array( array( '$lte' => array ( '$age', 32 )), 'age_26_32', 'age_Above_32' ) ) ) ) ) ), 'count' => array( '$sum' => 1 ) ) ) ); 

Также отмечая, что логические операторы сравнения, такие как $lt работают по-разному на этих этапах с их сопоставлениями запросов. Они сами принимают множество аргументов, являющихся значениями для проверки и сравнения. Они возвращают true/false на основе этого сравнения, что является требованием для первого аргумента для $cond .

Всегда удобно иметь json_encode где-нибудь, где вы отлаживаете форму запросов к конвейеру, поскольку JSON будет общей областью примеров:

 echo json_encode( $pipeline, JSON_PRETTY_PRINT ) . "\n"; 

Это дает общую структуру JSON:

 [ { "$group": { "_id": { "$cond":[ { "$lt":["$age",18] }, "age_0_17", { "$cond":[ { "$lte":["$age",25] }, "age_18_25", { "$cond":[ { "$lte":["$age",32] }, "age_26_32", "age_Above_32" ]} ]} ] }, "count":{ "$sum": 1 } }} ]