Mongo年龄组汇总 [英] Mongo Age Group Aggregation
问题描述
请考虑以下集合
$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));
有人可以帮助我获得年龄段内不同用户的数量吗? 例如,对于上面的模式,我想获得
Can anyone help me to get count of distinct users within a age group? For example for the schema above i would like to get
Age 0-17 = 0, Age 18-25 = 3, Age 26-32 = 0 Age > 32 = 1
我尝试使用 $ cond 运算符,但是没有设法使其发挥作用. 每当我尝试运行或更改它时,我都会收到以下两个错误之一:
I have tried to use the $cond operator but didn't manage to get it it work. Every time i try to run or change it i get one of the 2 errors:
- "$ cond"运算符需要3个操作数 或
- 管道阶段规范对象必须只包含一个字段.
- The "$cond" operator requires 3 operands or
- A pipeline stage specification object must contain exactly one field.
以下是我的查询,非常感谢您的帮助.预先感谢,
My query is bellow any help is much appreciated. Thanks in advance,
$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%对,它没有给我想要的输出,但领先 带我去了那里.
The Answer by @Neil Lunn is 90% right, it did not give me the desired output but leaded took me there.
使用Neil的查询,我得到的输出是:
With Neil's query the output i get is:
age_Above_32 = 1 and age_18_25 = 10
不同的user_id计数的输出应为
The output for distinct user_id count should be
age_Above_32 = 1 and age_18_25 = 3
要获得该信息,我只需要稍微调整一下Neil的查询即可. 最终查询如下.
To obtain that i just had to tweak Neil's query a little bit. The final query is below.
$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)
))
);
推荐答案
您来对地方了,但是您作为false
条件.因此,此处的语法有些不正确.
You were in the right place, but as $cond
requires three arguments (being the evaluation , true result and false result) you need to "nest" these operations, which each subsequent $cond
as the false
condition. So your syntax here is a little off.
您也可以只在 $group
,以避免使用单独的 $project
.根据您作为示例给出的文档结构,您将形成如下形式:
You can also do this just in the $group
to avoid passing through the whole collection with a separate $project
. Based on the document structure you give as an example you would form like this:
$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
的第一个参数的要求.
Also noting that logical comparison operators such as $lt
work differently in these stages to their query counterparts. They themselves take an array of arguments being the values to test and compare. They return true/false
based on that comparison, which is the requirement for the first argument to $cond
.
在调试管道查询形式的地方总是很方便地放置json_encode
,因为JSON将是示例的一般范围:
Always handy to have a json_encode
somewhere where you are debugging the form of pipeline queries, as JSON will be the general scope of examples:
echo json_encode( $pipeline, JSON_PRETTY_PRINT ) . "\n";
产生普通的JSON结构:
Which yields the common JSON structure:
[
{ "$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 }
}}
]
这篇关于Mongo年龄组汇总的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!