Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDb-Aggregate:如何获得单个未分组记录的总计?_Mongodb - Fatal编程技术网

MongoDb-Aggregate:如何获得单个未分组记录的总计?

MongoDb-Aggregate:如何获得单个未分组记录的总计?,mongodb,Mongodb,假设我们有如下文件: { type: "hourly", amount: 100 }, { type: "flat", amount: 350 }, { type: "hourly", amount: 200 }, { type: "payment", amount: 100 }, { type: "payment", amount: 200 } 在管道中的某个地方,我想累积每个“类型”的总计。连同所有单个记录,我想知道我们的总计如下所示: hourly: $300 flat: $35

假设我们有如下文件:

{ type: "hourly", amount: 100 },
{ type: "flat", amount: 350 },
{ type: "hourly", amount: 200 },
{ type: "payment", amount: 100 },
{ type: "payment", amount: 200 }
在管道中的某个地方,我想累积每个“类型”的总计。连同所有单个记录,我想知道我们的总计如下所示:

hourly:  $300
flat:    $350
payment: $300
myAggregate.push({
    "$group": {
        "_id": null, //"$transactionType",
        "documents": { "$push": "$$ROOT" },
        "hourlyTotal": {"$sum": "$hourlyAmount"},
        "flatTotal" :  {"$sum": "$flatAmount"},
        "paymentTotal" :  {"$sum": "$paymentAmount"},
        "expenseTotal" :  {"$sum": "$expenseAmount"},
        "creditTotal" :  {"$sum": "$creditAmount"},
        "debitTotal" :  {"$sum": "$debitAmount"},
    }
});
我已经研究了$add$sum,它们似乎对为给定记录添加字段很有用,而不是用于累计总计

到目前为止,我的聚合过滤了我想要的所有记录,并且没有使用分组。我不想把这些记录分组。我需要个人记录和总数

我相信如果我必须对$group-可能是$push-将单个记录放入一个数组以将其与所有其他记录一起取出,则$push命令可能是相关的。请看下面的答案:

在我的例子中,我有一个聚合,没有收集任何总数,如下所示。对于每个返回的文档,都有一个“类型”字段(例如,“小时”、“单位”、“付款”)

“myAggregate”是什么样子的,以便累计总计并返回所有单个(未分组)记录

深思熟虑后:如果“手动”遍历记录以获得总数对我来说同样有效,那么我可以做到。我认为MongoDb做这件事一定会更有效率,因为他们费心去做这些特性

编辑1:

以下是如何根据Veeram的建议添加“myAggregate”:

// Do we need to get only records which match the matter's contactId?
if (query2 != "") {
    myAggregate.push( { $match: query2 } );
}

// Get grand totals.
myAggregate.push({ "$group": { "_id": "$transactionType",
                "documents": { "$push": "$$ROOT" },
                "grandtotal": {"$sum":"$amount"}
           }
});

在Veeram的帮助下,我通过在他建议的
小组
阶段之前添加
项目
阶段来获得总数。我还将
的id设置为null(根据),以避免将所有文档分为组

    $project: {
        _id: 1,
        firmId: 1,

        ... plus, a bunch more fields.

        // Project some fields to allow totaling by transactionType.
        hourlyAmount: { $cond: { if: { $eq: ["$transactionType", "hourly"] }, then: "$amount", else: 0 } },
        flatAmount: { $cond: { if: { $eq: ["$transactionType", "flat"] }, then: "$amount", else: 0 } },
        paymentAmount: { $cond: { if: { $eq: ["$transactionType", "payment"] }, then: "$amount", else: 0 } },
        expenseAmount: { $cond: { if: { $eq: ["$transactionType", "expense"] }, then: "$amount", else: 0 } },
        creditAmount: { $cond: { if: { $eq: ["$transactionType", "credit"] }, then: "$amount", else: 0 } },
        debitAmount: { $cond: { if: { $eq: ["$transactionType", "debit"] }, then: "$amount", else: 0 } }

    }
然后,根据Veeram,我分组如下:

hourly:  $300
flat:    $350
payment: $300
myAggregate.push({
    "$group": {
        "_id": null, //"$transactionType",
        "documents": { "$push": "$$ROOT" },
        "hourlyTotal": {"$sum": "$hourlyAmount"},
        "flatTotal" :  {"$sum": "$flatAmount"},
        "paymentTotal" :  {"$sum": "$paymentAmount"},
        "expenseTotal" :  {"$sum": "$expenseAmount"},
        "creditTotal" :  {"$sum": "$creditAmount"},
        "debitTotal" :  {"$sum": "$debitAmount"},
    }
});

它工作得很好,所有内容都作为一个包含单个元素的数组返回。请注意,“documents”是数组元素的一个属性,因此它们可以被
[0]
.documents引用。我的所有个人总计都在那里(例如,
arrayElements>[0].hourlyTotal
)。

您可以添加
{“$group”:{“\u id”:“$type”,“documents”:{“$push”:“$$ROOT”},“grandtotal”:{$sum:$amount”}
作为最后一步。更多@Veeram,现在似乎是我学习如何正确构建表达式的时候了。我正在阅读关于的部分,但我不太明白它们是如何组合在一起的。事实上,我引用的关于表达式的部分根本不包含任何示例。你在上面使用了相当多的表达,我需要一个好的参考来理解每一个。例如,您没有在$sum周围包含引号。对于这样的建筑表达有什么好的参考吗?我只是错过了。当您引用文档字段并使用嵌入的属性名称时,这很重要。无论如何都要使用引号。读取[$group](),并有一些不同累加器的示例。$$ROOT是一个系统变量,它提供对当前文档的访问。@Veeram。谢谢我刚刚有机会尝试一下,看看结果如何。我看到1个数组[]和1个元素。第一个元素的id为:“hourly”,documents:,grandtotal:1235。结果不包括type==“flat”或任何其他类型的元素。即使为每种类型添加了额外的元素,我的结果仍将分组。我希望所有的结果都按自然顺序或任何排序顺序进行,而不需要分组。如果放弃分组并遍历所有元素以求和它们的数量对我来说同样有效,那么我可以这样做。请告诉我。不完全确定为什么只有一种类型出现。我需要查看完整的聚合查询以及用于运行代码的数据。关于分组问题:所以mongodb将数据从一个阶段传递到另一个阶段
$group
stage就像sql group要求您选择下一阶段所需的所有数据一样。如果您希望将数据展平,使每个小时文档包含相同的总计,您可以
{$unwind:$document”}
并在末尾添加
$sort
阶段,以向输出文档添加顺序。关于效率:您可以尝试这两种方法并比较指标。