Пожалуйста, рассмотрите сборник ниже
$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, но не смог заставить его работать. Каждый раз, когда я пытаюсь запустить или изменить его, я получаю одну из двух ошибок:
Мой запрос рев, любая помощь очень ценится. Заранее спасибо,
$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) )) );
Вы были в правильном месте, но поскольку $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 } }} ]