当前位置: 首页 > 知识库问答 >
问题:

使用Mongo聚合计算值之和

呼延承平
2023-03-14

我有发票,每张发票都包含一个项目列表。每个项目都有(除其他外)以下字段:

  • 姓名
  • 数量
  • 总计

每张发票都有(除其他外)字段:

  • _id
  • 创建
  • 项目

发票存在于专门的Mongo集合中,称为发票。

我想获取包含指定项目的所有发票,其中每个发票都需要返回以下信息:

  • _id

让我们称之为元组

如果发票列出给定项目两次,则相应的发票将生成两个投影实例。如果发票根本没有列出给定的项目,则结果中不存在此发票。

无论如何,我正在使用以下Mongo聚合管道检索所需的投影:

  pipeline = [
    {$match: {'items.name': req.params.name}},
    {$project: {created: 1, 'items.name': 1, 'items.qty': 1, 'items.total': 1}},
    {$unwind: '$items'},
    {$match: {'items.name': req.params.name}},
    {$project: {created: 1, qty: '$items.qty', total: '$items.total'}}
  ],

管道的工作原理如下:

  1. 首先匹配具有给定名称的项目的所有发票。在<代码>项上有一个Mongo索引。名称,所以这个$匹配是有效的
  2. 发票是一个大对象,因此请去掉所有字段,只留下以下结构:{code>{u id:?,created:?,items:[{name:?,qty:?,total:?}。。。,{名称:?,数量:?,总数:?}]}
  3. 展开items数组,现在我们有了一个{id:?,创建:?,'items.name':?,'items.qty':?,'items.total':?} 对象
  4. 删除与给定名称不匹配的所有项目
  5. 塑造最终发票投影

然后通过以下代码执行发票预测的最终列表:

function prepareResult(projections) {
  var res = projections.reduce(function (acc, item) {
    acc.itemCount += item.qty;
    acc.total += item.total;
    delete item.total;
    return acc;
  }, {itemCount: 0, total: 0});
  res.items = projections;
  return res;
}

它对所有发票预测中的“数量”和“总计”字段求和,并返回一个包含预测和计算总数的新对象。从每个发票预测中删除“总计”字段,因为它只是需要的最终金额。

我的问题-我可以将prepareResult函数的逻辑移到Mongo聚合管道中吗?


共有1个答案

安轶
2023-03-14

您需要向管道中添加$组步骤。

组的\u id将是求和的依据(在本例中是一个常量,因为您需要一个总计)。由于要保留发票列表,可以通过$push操作符将其累积到数组字段中。总数和数量的总和将用$sum处理。

{$group : { _id : 1,
            Total : { $sum : "$total" },
            ItemCount : { $sum : "$qty" },
            Invoices : { $push : { id : "$_id", created : "$created" }}
} }
 类似资料:
  • 我有一个集合xyz,我需要在不使用MongoDB的情况下找到列分支的所有唯一值。distinct方法。我知道我们可以通过group by来完成,这会给我一个对象数组作为结果,但我需要字符串数组作为输出,比如['a','b','c'。我不知道如何以这种方式格式化它,仅在mongo查询中。 数据库。getCollection(“xyz”)。聚合([{$组:{“\u id”:“$分支”},}])

  • 我有一个mongo搜索集。每个搜索都有一个criteria对象,该对象可以有任何条件组合。比如: 我正在构建一个mongo聚合管道,我想知道如何只投影密钥,以便我可以计算它们。 到目前为止,我的管道的第一步是: 这将正确返回所有criteria对象,现在我需要以某种方式投影键。有人有什么想法吗? 编辑:所需输出:

  • 我搜索了类似的问题,但没有找到任何问题。请随时为我指出他们的方向。 假设我有这个数据: 如果我想获取每个属性组的最新记录,我可以这样做: 我想让我的数据按属性分组,然后按id排序,这样每个组中只保留最新的记录,这就是我可以做到的。但我需要一种方法来避免在结果中命名我想要的所有字段(在本例中为“name”),因为在我的实际用例中,它们在前面是未知的。 那么,有没有办法做到这一点,但不必使用$last

  • 我试图使用ObjectId作为创建日期持有人,在尝试执行聚合查询时遇到了一些问题。特别是,我们希望使用日期聚合运算符按月份对文档进行分组,但该运算符显然不适用于ObjectId。是否有办法解决这个问题,或者我必须开始在每个文档中使用单独的CreationTime字段? 下面是我尝试的一个查询-

  • 您好,朋友,我对mongodb聚合不友好,我想要的是,我有一个对象数组,其中包含每个问题的主题分数,我使用的是节点js,所以我想要的是,如果可能的话,使用mongo查询进行完整计算,包括主题名称及其总分和尝试次数,不尝试我的Json数组如下 在对象中,一个字段用于正确标记主题不同,我希望输出如下 我正在尝试聚合,但尚未完成我已尝试此查询 任何人都知道如何实现这种类型的输出。而如果用另一种方式来实现

  • 大家好,我有一个大问题在查询我的数据。我有这样的文件: 我想构建两个查询: 1)每天计算标签的数量,然后输出,例如,如下所示: 2)另一个是相同的,但我想设置一个期间从2016-12-13到2016-12-17。 对于第一个查询,我编写了这个查询,并得到了我所搜索的内容,但是在Spring Data Mongo中,我不知道如何编写。