我保留了一系列事件,按日计算。如果事件发生一次,则它是'hit'(billState),这是每个位置和材料类。我很难将数据恢复到我需要的状态,我已经尝试了几个在SO上找到的例子,而且许多在Mongo Docs中...通常最终只得到我需要的部分内容。
我的收藏样本是这样的:
{
"_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")
}
我可以有几个地点和materialClasses和我只是想计算“billState”是否为一(很容易因为它不会在集合中)。我需要按周,地点,日期,材料类分解它......就像这样......
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
目前,我只能(另一方面)在另一个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
}
这就是我现在所拥有的......
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" }
]);
};
我尝试过使用更多的$ groups,$ match和与$ project混淆,但似乎无法按日期将其分解,包括位置。真的,我只需要计算每天,地点和材料类别的事件,然后每周和每月的总和。因此,在任何一天,可能会在一个位置点击20个物质类别,在另一个位置点击“X”金额等等。每个级别每个位置每天只计算一次点击。
编辑: 输出示例(我认为这是一个好主意..,这是漫长的一天)
{
"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
}
]
}
}
}
}
答案 0 :(得分:0)
我已经有一段时间了,因为我在MongoDB中使用了聚合方法。我把它和你的模拟数据放在一起。不幸的是没有得到确切的结果;也许它仍然会有所帮助。祝好运。
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()
查询结果返回
{
"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
}
}