【问题标题】:MongoDB: Counting how many of each distinct values there are?MongoDB:计算每个不同的值有多少?
【发布时间】:2016-03-09 08:58:29
【问题描述】:

我有一组文档,其中包含针对不同项目的反馈列表。它看起来像这样:

{
  {
    item: "item_1"
    rating: "neutral"
    comment: "some comment"
  },
  {
    item: "item_2"
    rating: "good"
    comment: "some comment"
  },
  {
    item: "item_1"
    rating: "good"
    comment: "some comment"
  },
  {
    item: "item_1"
    rating: "bad"
    comment: "some comment"
  },
  {
    item: "item_3"
    rating: "good"
    comment: "some comment"
  },
}

我想要一种方法来找出每个项目有多少不同的评分。

所以输出应该是这样的:

{
  {
    item: "item_1"
    good: 12
    neutral: 10
    bad: 67
  },
  {
    item: "item_2"
    good: 2
    neutral: 45
    bad: 8
  },
  {
    item: "item_3"
    good: 1
    neutral: 31
    bad: 10
  }

}

这就是我所做的

db.collection(collectionName).aggregate(
          [
             {
               $group:
                 {
                   _id: "$item",
                   good_count: {$sum: {$eq: ["$rating",  "Good"]}},
                   neutral_count:{$sum: {$eq: ["$rating",  "Neutral"]}},
                   bad_count:{$sum: {$eq: ["$rating",  "Bad"]}},
                 }
             }
           ]
)

输出的格式看起来正确,但计数始终为 0。

我想知道通过查看同一字段的不同值来总结事情的正确方法是什么?

谢谢!

【问题讨论】:

    标签: javascript mongodb aggregation-framework


    【解决方案1】:

    您非常接近,但当然$eq 只返回一个true/false 值,因此要使该数字成为您需要$cond

    db.collection(collectionName).aggregate([
      { "$group" : {
           "_id": "$item",
           "good_count": { 
               "$sum": { 
                   "$cond": [ { "$eq": [ "$rating",  "good" ] }, 1, 0] 
               }
           },
           "neutral_count":{
               "$sum": { 
                   "$cond": [ { "$eq": [ "$rating", "neutral" ] }, 1, 0 ]
                }
           },
           "bad_count": { 
               "$sum": { 
                   "$cond": [ { "$eq": [ "$rating",  "bad" ] }, 1, 0 ]
               }
           }
      }}
    ])
    

    作为“三元”运算符$cond 将逻辑条件作为它的第一个参数 (if),然后返回第二个参数,其中评估为 true (then) 或第三个参数 false (else) .这使得true/false 返回到10 分别提供给$sum

    另请注意,“大小写”对$eq 敏感。如果您有不同的大小写,那么您可能希望在表达式中使用$toLower

                   "$cond": [ { "$eq": [ { "$toLower": "$rating" },  "bad" ] }, 1, 0 ]
    

    稍微不同的是,以下聚合通常对不同的可能值更灵活,并且在性能方面围绕条件和运行:

    db.collection(collectionName).aggregate([
        { "$group": {
            "_id": { 
                "item": "$item",
                "rating": { "$toLower": "$rating" }
            },
            "count": { "$sum": 1 }
        }},
        { "$group": {
            "_id": "$_id.item",
            "results": {
                "$push": {
                    "rating": "$_id.rating",
                    "count": "$count"
                }
            }
        }}
    ])
    

    这将给出如下输出:

    {
        "_id": "item_1"
        "results":[
            { "rating": "good", "count": 12 },
            { "rating": "neutral", "count": 10 }
            { "rating": "bad", "count": 67 }
        ]
    }
    

    这些都是相同的信息,但您不必显式匹配这些值,这样执行起来会快得多。

    【讨论】:

      猜你喜欢
      • 2019-07-24
      • 2011-07-28
      • 2018-07-30
      • 1970-01-01
      • 1970-01-01
      • 2016-02-26
      • 2019-04-30
      • 1970-01-01
      • 2017-07-28
      相关资源
      最近更新 更多