我可以使用什么mongo查询来获取日期范围内特定字段的不同值计数?

时间:2018-03-22 17:52:34

标签: mongodb

我们说我有一个水果田。我做了一个从3月19日到3月21日的日期范围查询,但想要计算每天不同类型的水果人吃的数量,以及他们每天吃多少次。

这是我到目前为止所拥有的。



db.getCollection('fruits').aggregate([
  {
    "$match": {
      "dates": {
        "$gte": new Date(2018, 02, 19, 00, 00, 00),
        "$lt": new Date(2018, 02, 21, 00, 00, 00)
      }
    }
  },
  {
    "$group": {
      "_id": {
        year: {
          $year: "dates"
        },
        month: {
          $month: "dates"
        },
        day: {
          $dayOfMonth: "dates"
        },
        "fruitField": "$fruits"
      },
      "count": { "$sum": 1 }
    }
  }
]




编辑:

预期输出将是这样的: 19日: 橘子:17 苹果:19 梨:8

20: 橘子:6 梨:4

21: 橙子:3 苹果:10 梨:4

1 个答案:

答案 0 :(得分:1)

使用MongoDb 3.6及更新版本,您可以利用 $arrayToObject 运算符和 $replaceRoot 管道来获得所需的结果。您需要运行以下聚合管道:

db.getCollection('fruits').aggregate([
    { "$match": {
        "dates": {
            "$gte": new Date(2018, 02, 19, 00, 00, 00),
            "$lt": new Date(2018, 02, 21, 00, 00, 00)
        }
    } },
    {  "$group": {
        "_id": {  
            "fruit": { "$toLower": "$fruits" },
            "day": { "$dayOfMonth": "$dates" }
        },
        "count": { "$sum": 1 }
    } },
    { "$group": {
        "_id": "$_id.day",
        "counts": {
            "$push": {
                "k": "$_id.fruit",
                "v": "$count"
            }
        }
    } },
    { "$replaceRoot": { 
        "newRoot": { 
            "$mergeObjects": [ 
                { "$arrayToObject": "$counts" }, 
                "$$ROOT" 
             ] 
        } 
    } },
    { "$project": { "counts": 0 } } 
])

对于旧版本,$cond管道步骤中的$group运算符可以有效地用于根据fruits字段值评估计数。您可以按如下方式构建整体聚合管道,以便以所需格式生成结果:

db.getCollection('fruits').aggregate([
    { "$match": {
        "dates": {
            "$gte": new Date(2018, 02, 19, 00, 00, 00),
            "$lt": new Date(2018, 02, 21, 00, 00, 00)
        }
    } },
    { 
        "$group": { 
            "_id": { "$dayOfMonth": "$dates" },             
            "Oranges": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$fruits", "Oranges" ] }, 1, 0 ]
                }
            },
            "Apples": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$fruits", "Apples" ] }, 1, 0 ]
                }
            },
            "Pears": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$fruits", "Pears" ] }, 1, 0 ]
                }
            } 
        }  
    }
])

对于未知和可能的水果值,您可以采用不同的管道:

db.collection('fruits').aggregate([
    { "$match": {
        "dates": {
            "$gte": new Date(2018, 02, 19, 00, 00, 00),
            "$lt": new Date(2018, 02, 21, 00, 00, 00)
        }
    } },
    { "$group": {
        "_id": { 
            "day": { "$dayOfMonth": "$dates" },
            "fruit": { "$toLower": "$fruits" }
        },
        "count": { "$sum": 1 }
    } },
    { "$group": {
        "_id": "$_id.day",
        "counts": {
            "$push": {
                "fruit": "$_id.fruit",
                "count": "$count"
            }
        }
    } }
])