node.js - 如何根据用户提供的过滤器执行多层临时聚合?
问题描述
我的文档架构如下所示:
{
name: "John Doe",
City : "OK",
Prepaid: "Y",
Ethnicity: 'a',
Zip: '06516'
},
{
name: "Jane Doe",
City : "CA",
Prepaid: "N",
Ethnicity: 'b'
Zip: '12321'
},
{
name: "Jule Doe",
City : "OK",
Prepaid: "N",
Ethnicity: 'a'
Zip: '06516'
},
{
name: "Jake Doe",
City : "OK",
Prepaid: "Y",
Ethnicity: 'a',
zip: '06516'
}
我正在尝试将它们分组为多个层并基于此获得计数。唯一需要注意的是,用于分组参数的过滤器可以是文档中的任何内容。
我想要得到的东西看起来像这样:
如果用户选择按 City 和 Prepaid 对它们进行分组,那么它将如下所示:
{
City : OK
Count : {
"filter": prepaid,
"count": {
Y : 2
N: 1
}
}
}
{
City : CA
Count : {
"filter": prepaid,
"count": {
Y : 0
N: 1
}
}
}
但如果用户选择 Ethnicity 和 Prepaid,它看起来像这样。
{
Ethinicity : A,
City: OK
Count : {
"filter": prepaid,
"count": {
Y : 2
N: 1
}
}
}
{
Ethinicity : B,
City: CA
Count : {
"filter": prepaid,
"count": {
Y : 1
N: 0
}
}
}
我试过这样做:
const countVals = await PhoneSamplingCollection.aggregate([
{ $match: fullQuery },
{$group: groupquery //variable that has object provided by user to group on
, count:{$sum:1}}}
]).exec();
它只给我一起计数而不是分解。
解决方案
您可以尝试以下查询:
更新答案:
如果您在Prepaid字段中有多个选项可以分组,请尝试以下查询:
db.collection.aggregate([
/** Group on city & prepaid & count no.of docs matches each criteria */
{
$group: { _id: { City: "$City", Prepaid: "$Prepaid" }, Count: { $sum: 1 } }
},
/** Group only on City to push all data to a field Count */
{
$group: {
_id: "$_id.City",
Count: { $push: { k: "$_id.Prepaid", v: "$Count" } }
}
},
/** Transform fields using project stage &
* use 'arrayToObject' to convert count array of objects to an object with {k:...,v:...} */
{ $project: { _id: 0, City: "$_id", Count: { $arrayToObject: "$Count" } } },
{ $project: { City: 1, Count: { count: "$Count", filter: "Prepaid" } } }
]);
测试: MongoDB-游乐场
旧答案:
db.collection.aggregate([
{
$group: {
_id: "$City",
Y: { $sum: { $cond: [{ $eq: ["$Prepaid", "Y"] }, 1, 0] } },
N: { $sum: { $cond: [{ $eq: ["$Prepaid", "N"] }, 1, 0] } }
}
},
{
$project: {
_id: 0,
City: "$_id",
Count: { filter: "Prepaid", count: { Y: "$Y", N: "$N" } }
}
}
]);
测试: MongoDB-游乐场
因此,在您的代码中,您将根据用户的选择构建查询并根据条件在它们之间切换。如果您也需要,请测试以下查询Ethinicity
。
db.collection.aggregate([
{
$group: {
_id: {
City: "$City",
Ethnicity: "$Ethnicity"
},
Y: { $sum: { $cond: [{ $eq: ["$Prepaid", "Y"] }, 1, 0] } },
N: { $sum: { $cond: [{ $eq: ["$Prepaid", "N"] }, 1, 0] } }
}
},
{
$project: {
_id: 0,
City: "$_id.City",
Ethnicity: "$_id.Ethnicity",
Count: { filter: "Prepaid", count: { Y: "$Y", N: "$N" } }
}
}
]);
测试: MongoDB-游乐场
推荐阅读
- xbee - XBee3 协调器在网络发现期间找不到 End_Device
- java - Java 自动装箱 int 到 Long
- postgresql - 无法使用通过 ansible 创建的 postgresql 用户登录
- ios - didWriteValueFor 在尝试使用 .writeValue 写入时未第二次调用
- internet-explorer - 启用代理服务器时互联网速度慢
- python-3.x - AttributeError:“NoneType”对象没有属性“大小”
- css - 如何删除css flex包含之间的空间
- javascript - 如何使用 Chai 进行测试
- c# - 如何拥有多个相同类型的 DbContext?
- javascript - 时刻 js 没有返回给定周+年的正确日期