我有包含日期​​字段的集合。我正在按周和其他相关领域对记录进行分组。

这是我的聚合查询:

db.raw.aggregate([
    { "$match" : {
        "Timestamp":{
            "$gte": new Date("2012-05-30"),
            "$lt": new Date("2014-07-31")
        }
    }},
    { "$group" : {
        "_id":{
            "ApplicationId": "$ApplicationId",
            "Country": "$Country",
            "week":{ "$week": "$Timestamp" }
        },
        "Date":{ "$first": "$Timestamp" },
        "Visits": { "$sum": 1 }
    }}
])

我想从周数预测:访问次数和一周的开始日期。

最佳答案

您似乎想要一个“日期值”来表示一周开始的日期。在聚合运算符 $dayOfWeek 的帮助下,您最好的方法是“日期数学”:

db.raw.aggregate([
  { "$match" : {
    "Timestamp":{
      "$gte": new Date("2012-05-30"),
      "$lt": new Date("2014-07-31")
    }
  }},
  { "$group" : {
    "_id":{
      "ApplicationId": "$ApplicationId",
      "Country": "$Country",
      "weekStart":{
        "$subtract": [
          { "$subtract": [
            { "$subtract": [ "$Timestamp", new Date("1970-01-01") ] },
            { "$cond": [
              { "$eq": [{ "$dayOfWeek": "$Timestamp" }, 1 ] },
              0,
              { "$multiply": [
                1000 * 60 * 60 * 24,
                { "$subtract": [{ "$dayOfWeek": "$Timestamp" }, 1 ] }
              ]}
            ]}
          ]},
          { "$mod": [
            { "$subtract": [
              { "$subtract": [ "$Timestamp", new Date("1970-01-01") ] },
              { "$cond": [
                { "$eq": [{ "$dayOfWeek": "$Timestamp" }, 1 ] },
                0,
                { "$multiply": [
                  1000 * 60 * 60 * 24,
                  { "$subtract": [{ "$dayOfWeek": "$Timestamp" }, 1 ] }
                ]}
              ]}
            ]},
            1000 * 60 * 60 * 24
          ]}
        ]
      }
    },
    "Date":{ "$first": "$Timestamp" },
    "Visits": { "$sum": 1 }
  }}
])

或者使用 MongoDB 2.6 及更高版本的 $let 更清洁一点:

db.raw.aggregate([
  { "$match" : {
    "Timestamp":{
      "$gte": new Date("2012-05-30"),
      "$lt": new Date("2014-07-31")
    }
  }},
  { "$group" : {
    "_id":{
      "ApplicationId": "$ApplicationId",
      "Country": "$Country",
      "weekStart":{
        "$let": {
          "vars": {
            "dayMillis": 1000 * 60 * 60 * 24,
            "beginWeek": {
              "$subtract": [
                { "$subtract": [ "$Timestamp", new Date("1970-01-01") ] },
                { "$cond": [
                  { "$eq": [{ "$dayOfWeek": "$Timestamp" }, 1 ] },
                  0,
                  { "$multiply": [
                    1000 * 60 * 60 * 24,
                    { "$subtract": [{ "$dayOfWeek": "$Timestamp" }, 1 ] }
                  ]}
                ]}
              ]
            }
          },
          "in": {
            "$subtract": [
              "$$beginWeek",
              { "$mod": [ "$$beginWeek", "$$dayMillis" ]}
            ]
          }
        }
      }
    },
    "Date":{ "$first": "$Timestamp" },
    "Visits": { "$sum": 1 }
  }}
])

“分组”中的结果值是代表一周开始时一天开始的纪元毫秒。 “一周的开始”通常被认为是“星期日”,因此如果您打算改天,则需要进行适当的调整。例如,带有 $add 变量值的 $dayMillis 运算符可在此处用于应用“星期一”。

它不是日期对象,而是您可以轻松提供给另一种方法以在后期处理中构造日期对象的东西。

另请注意,您使用的其他东西(例如 $first )通常要求文档按特定顺序排序,或者通常按“时间戳”值排序。如果这些文档尚未排序,则您可以先 $sort 或使用诸如 $min 之类的运算符来获取范围内的第一个实际时间戳。

关于mongodb - 从mongodb中的周数获取一周的第一天,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25013090/

10-16 09:33