简体   繁体   English

根据日期和其他字段汇总Mongo集合中的数据,然后进行计数

[英]Aggregate data from Mongo collection based on dates and other fields, and count

I keep a collection of events, counting by day. 我会收集事件,按天计数。 If the event occurs once then it's a 'hit' (billState), this is per location and material class. 如果事件发生一次,则为“命中”(billState),这是按位置和物料类别分类的。 I am having a hard time getting the data back out that I need, I have tried several examples found here at SO, and many in the Mongo Docs.. usually ending up with only parts of what I need to get out. 我很难找回所需的数据,我尝试了一些在SO上找到的示例,以及Mongo Docs中的许多示例。通常最后只得到了我需要删除的部分内容。

Sample of my collection is like this: 我的收藏样本如下:

{
    "_id" : ObjectId("565ca8678e000995a09d1540"),
    "company" : "someCompany",
    "location" : "123",
    "materialCode" : "MATCODE",
    "materialClass" : "Class",
    "totalCount" : 8,
    "billState" : 1,
    "eventTime" : ISODate("2015-11-30T19:49:59.243Z")
}

{
    "_id" : ObjectId("565ca9778e000995a09d1541"),
    "company" : "someCompany",
    "location" : "1",
    "materialCode" : "WTHFA",
    "materialClass" : "OtherClass",
    "totalCount" : 16,
    "billState" : 1,
    "eventTime" : ISODate("2015-11-30T19:54:31.695Z")
}

{
    "_id" : ObjectId("565ca9778e000995a09d1541"),
    "company" : "someCompany",
    "location" : "12345",
    "materialCode" : "WTHFA",
    "materialClass" : "thirdClassOfMat",
    "totalCount" : 16,
    "billState" : 1,
    "eventTime" : ISODate("2015-11-30T19:54:31.695Z")
}

I can have several locations & materialClasses and I am only trying to count if "billState" is one (easy because it will not be in the collection otherwise). 我可以有几个位置和materialClasses,我只想计算“ billState”是否为一个(容易,因为否则它将不在集合中)。 I need to break it down by Week, location, day, material class.. like so.. 我需要按周,位置,日期,材料分类来细分它。

    week1 mon tue wed thur fri sat sun
          ----------------------------
location 1  -  -   -  Class otherClass  = 2 
location 123-  -   -  Class otherClass  = 2 
    week2 mon tue wed thur fre sat sun
          ----------------------------
locations    material billState Count   = X
                                       -----
                                       month total

Currently I can only get to this, based mostly (at this point) on another SO post: 目前,我只能(主要)基于另一篇SO帖子来了解这一点:

{
    "_id" : 12,
    "weeks" : {
        "week" : 48,
        "total" : 6,
        "days" : [ 
            {
                "day" : ISODate("2015-12-02T00:00:00.000Z"),
                "total" : 1
            }, 
            {
                "day" : ISODate("2015-12-01T00:00:00.000Z"),
                "total" : 1
            }, 
            {
                "day" : ISODate("2015-11-30T00:00:00.000Z"),
                "total" : 4
            }
        ]
    },
    "monthTotal" : 6
}

This is what I have now.. 这就是我现在所拥有的..

myCollection.aggregate([

        // then total per day. Rounding dates
        { "$group": {
            "_id": {
                "$add": [
                    { "$subtract": [
                        { "$subtract": [ "$eventTime", new Date(0) ] },
                        { "$mod": [
                            { "$subtract": [ "$eventTime", new Date(0) ] },
                            1000 * 60 * 60 * 24
                        ]}                        
                    ]},
                    new Date(0)
                ]
            },
            "week": { "$first": { "$week": "$eventTime" } },
            "month": { "$first": { "$month": "$eventTime" } },
            "total": { "$sum": "$billState" }
        }},

        // Then group by week
        { "$group": {
            "_id": "$week",
            "month": { "$first": "$month" },
            "days": {
                "$push": {
                    "day": "$_id",
                    "total": "$total"
                }
            },
            "total": { "$sum": "$total" }
        }},

        // Then group by month
        { "$group": {
            "_id": "$month",
            "weeks": {
                "$push": {
                    "week": "$_id",
                    "total": "$total",
                    "days": "$days"
                }
            },
            "monthTotal": { "$sum": "$total" }
        }},

        {"$unwind": "$weeks"},

        { $out : "billingTotals" }
    ]);
};

I have tried using more $groups, $match and messed with $project but just can't seem to get it broken down far enough by date and including the locations. 我尝试使用更多的$ groups,$ match和$ project搞乱了,但是似乎无法按日期和位置将其分解得足够远。 Really I just need to count the event per day, location, and material class and then sum per week and month. 真的,我只需要统计每天,地点和材料类别的事件,然后每周和每月总计。 So, on any given day there may be hits for 20 material classes in one location, "X" amount in another location, etc. I will only count a single hit per day, per locaiton, per class. 因此,在任何给定的一天,一个位置可能有20种材料类别的匹配,另一位置可能有“ X”个数量的匹配,依此类推。我每天只计算一次每个位置,每个位置的匹配。

Edit: Example of output (I think this is a good idea.., it's been a long day) 编辑:输出示例(我认为这是一个好主意..,这已经是漫长的一天了)

{
    "month" : 12 {
        "week" : 49 {
            "day" : 3 {
                "location": "123",
                "materials": [
                                {
                                    "class": "materialClass",
                                    "total" : 2
                                },

                                {
                                    "class": "otherMatClass",
                                    "total" : 5
                                }
                             ],
                "location": "1234",
                                "materials": [
                                {
                                    "class": "materialClass",
                                    "total" : 2
                                },

                                {
                                    "class": "otherMatClass",
                                    "total" : 5
                                }
                             ],

            },
            "day" : 4 {
                "location": "123",
                "materials": [
                                {
                                    "class": "materialClass",
                                    "total" : 2
                                },

                                {
                                    "class": "otherMatClass",
                                    "total" : 5
                                }
                             ]
            }

        },
        "week" : 50 {
            "day" : 3 {
                "location": "123",
                "materials": [
                                {
                                    "class": "materialClass",
                                    "total" : 2
                                },

                                {
                                    "class": "otherMatClass",
                                    "total" : 5
                                }
                             ]

            }
        }


    }
}

It has been a while since I have used aggregate method in MongoDB. 自从我在MongoDB中使用聚合方法以来已经有一段时间了。 I put this together with your mock data. 我将其与您的模拟数据放在一起。 Unfortunately did not get exact result; 不幸的是没有得到确切的结果。 maybe it will still help. 也许它仍然会有所帮助。 Good luck. 祝好运。

db.materials.aggregate([
    {
      $match: {billState:{$ne:0}}
    },
    {
      $group: {
        _id:{location:"$location",date:{week:{$week:"$eventTime"},month:{$month:"$eventTime"},day:{$dayOfMonth:"$eventTime"},year:{$year:"$eventTime"}}},
        materials:{$addToSet:{code:"$materialCode",class:"$materialClass"}},
      }
    },
    {
      $sort:{"_id.date": 1}
    },
    {
      $group: {
        _id:{date:"$_id.date"},
        locations: {$addToSet:  {location:"$_id.location",materials:"$materials"}},
      }
    },
    {
      $project:{_id:0, date:"$_id.date",locations:1}
    }
]).pretty()

Result of query returns 查询返回结果

{
    "locations" : [
        {
            "location" : "123",
            "materials" : [
                {
                    "code" : "MATCODE",
                    "class" : "Class"
                }
            ]
        },
        {
            "location" : "1",
            "materials" : [
                {
                    "code" : "WTHFA",
                    "class" : "OtherClass"
                }
            ]
        },
        {
            "location" : "12345",
            "materials" : [
                {
                    "code" : "WTHFA",
                    "class" : "thirdClassOfMat"
                },
                {
                    "code" : "WTHFC",
                    "class" : "thirdClassOfMatter"
                }
            ]
        }
    ],
    "date" : {
        "week" : 48,
        "month" : 11,
        "day" : 30,
        "year" : 2015
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM