【问题标题】:How to sum distinct values of a field in a MongoDB collection (utilizing mongoose)如何对 MongoDB 集合中字段的不同值求和(利用 mongoose)
【发布时间】:2015-01-28 13:35:56
【问题描述】:

假设我有一个名为 journals 的集合,其中包含如下文档:

{
  "article": "id1",
  "d": 2
},
{
  "article": "id1",
  "d": 2
},
{
  "article": "id1",
  "d": 3
},
{
  "article": "id2",
  "d": 2
},
...

d 是一种开关,article 是一种参考。现在我想得到如下结果:

[
  {
    "_id": "id1",
    "total": 3,
    "d2": 2,
    "d3": 1
  },
  {
    "_id": "id2",
    "total": 1,
    "d2": 1,
    "d3": 0
  }
]

我正在使用 mongoose 并有一个名为 Journal 的模型。到目前为止,我得到的是……

Journal.aggregate(
  { $project: {
    articleId: 1,
    depth2 : { $gte:['$d', 2] },
    depth3 : { $eq:['$d', 3] }
  }},
  { $group: {
      _id: '$article',
      total: { $sum: 1 },
      d2: { $sum: '$depth2'},
      d3: { $sum: '$depth3'}
    }
  },
  function (err, journal) {
    console.log(journal);
  }
);

导致:

[
  {
    "_id": "id1",
    "total": 3,
    "d2": 0,
    "d3": 0
  },
  {
    "_id": "id2",
    "total": 1,
    "d2": 0,
    "d3": 0
  }
]

显然这里的错误是 $eq:['$d', 3] 没有被求和,因为这会导致一个布尔值。

那么有没有更好的表达式将新的 depth2 和 depth3 字段投影到 10 而不是 truefalse
或者是有完整更好的方法吗? :)

我想避免进行 3 次查询并预先设置匹配阶段,例如 { $match: { d: 2 } }

【问题讨论】:

    标签: node.js mongodb mongoose aggregation-framework


    【解决方案1】:

    您可以使用 $cond 将布尔值转换为数值,但您也有一个 $gte 似乎应该是 $eq 并且您的文档使用 article 而您的代码使用 @987654326 @:

    Journal.aggregate([
      { $project: {
        article: 1,
        depth2 : { $cond: [{$eq: ['$d', 2]}, 1, 0] },
        depth3 : { $cond: [{$eq: ['$d', 3]}, 1, 0] }
      }},
      { $group: {
          _id: '$article',
          total: { $sum: 1 },
          d2: { $sum: '$depth2'},
          d3: { $sum: '$depth3'}
        }
      }
    ]);
    

    输出:

    {
        "result" : [ 
            {
                "_id" : "id2",
                "total" : 1,
                "d2" : 1,
                "d3" : 0
            }, 
            {
                "_id" : "id1",
                "total" : 3,
                "d2" : 2,
                "d3" : 1
            }
        ],
        "ok" : 1
    }
    

    【讨论】:

    • 这就像圣诞节,非常感谢!是的,您对 articleId 的看法是正确的,它发生在简化示例的过程中。至于 $gte,这是故意的,因为它符合我的需要。所以 d 不完全是一个开关,我在撒谎,但是关于在 SO 上提问的问题,我已经尽我所能描述了 :) 再次感谢您的时间!
    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2012-10-31
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 1970-01-01
    相关资源
    最近更新 更多