1

我正在尝试跟踪个人的每日统计数据。

我很难在“历史”中添加新的一天,并且还可以在新数据进入时使用指针来更新“walkingSteps”。

我的架构看起来像:

{
"_id": {
    "$oid": "50db246ce4b0fe4923f08e48"
},
"history": [
    {
        "_id": {
            "$oid": "50db2316e4b0fe4923f08e12"
        },
        "date": {
            "$date": "2012-12-24T15:26:15.321Z"
        },
        "walkingSteps": 10,
        "goalStatus": 1
    },
    {
        "_id": {
            "$oid": "50db2316e4b0fe4923f08e13"
        },
        "date": {
            "$date": "2012-12-25T15:26:15.321Z"
        },
        "walkingSteps": 5,
        "goalStatus": 0
    },
    {
        "_id": {
            "$oid": "50db2316e4b0fe4923f08e14"
        },
        "date": {
            "$date": "2012-12-26T15:26:15.321Z"
        },
        "walkingSteps": 8,
        "goalStatus": 0
    }
]

}

db.history.update(?)

我一直在浏览(并尝试)mongodb 文档,但他们并没有完全将其分解为像我这样的傻瓜......我无法将他们的示例完全转换为我的设置。

谢谢你的帮助。

E = 尝试学习编程的菜鸟

4

3 回答 3

5

添加一天:

user = {_id: ObjectId("50db246ce4b0fe4923f08e48")}
day = {_id: ObjectId(), date: ISODate("2013-01-07"), walkingSteps:0, goalStatus: 0}
db.users.update(user, {$addToSet: {history:day}})

更新walkingSteps:

user = ObjectId("50db246ce4b0fe4923f08e48")
day = ObjectId("50db2316e4b0fe4923f08e13") // second day in your example
query = {_id: user, 'history._id': day}

db.users.update(query, {$set: {"history.$.walkingSteps": 6}})

这使用$ 位置运算符

不过,拥有一个单独的历史集合可能更容易。


[编辑] 在单独的集合上:

  • 添加天数会增加文档的大小,并且可能需要在磁盘上重新定位。这可能会导致性能问题和碎片化。
  • 删除天数不会缩小磁盘上的文档大小。
  • 它使查询更容易/直接(例如搜索一段时间)
于 2013-01-06T18:57:23.587 回答
1

尽管@Justin Case 给出了正确的答案,但他并没有很好地解释其中的一些事情。

您首先会注意到他摆脱了日期的分辨率并将它们的格式移动到仅日期而不是日期和时间,如下所示:

day = {_id: ObjectId(), date: ISODate("2013-01-07"), walkingSteps:0, goalStatus: 0}

这意味着您的所有日期都将具有00:00:00他们的时间,而不是您使用 atm 的确切时间。这增加了每天查询的便利性,因此您可以执行以下操作:

db.col.update(
    {"_id": ObjectId("50db246ce4b0fe4923f08e48"), 
    "history.date": ISODate("2013-01-07")}, 
    {$inc: {"history.$.walkingSteps":0}}
)

和其他类似的查询。

这也使得 $addToSet 实际上执行了它的规则,但是由于这个子文档中的数据可能会改变,即walkingSteps增量$addToSet在这里无论如何都不会很好地工作。

这是我会从勾选的答案中改变的东西。我可能会使用$push或其他东西,因为$addToSet它更重并且不会在这里真正做任何有用的事情。

在我看来,单独的历史收集的原因是你之前所说的:

是的,当天的历史项目数量。

所以这个数组包含一组天,这很好,但听起来你希望从中获得的数字walkingSteps,一组历史项目,应该在另一个集合中,你walkingSteps根据其中项目数量的计数进行设置今天的其他收藏:

db.history_items.find({date: ISODate("2013-01-07")}).count();
于 2013-01-06T19:36:15.520 回答
0

参考MongoDB 手册$是位置运算符,它标识要更新的数组字段中的元素,而无需显式指定元素在数组中的位置。位置 $ 运算符,与 update() 方法一起使用时,充当更新查询选择器的第一个匹配项的占位符。

因此,如果您发出命令来更新您的收藏,如下所示:

db.history.update(
   {someCriterion: someValue },
   { $push: { "history": 
               {"_id": {
                   "$oid": "50db2316e4b0fe4923f08e12"
               },
              "date": {
                   "$date": "2012-12-24T15:26:15.321Z"
               },
           "walkingSteps": 10,
           "goalStatus": 1
           } 
   } 
)

Mongodb 可能会尝试将$oid$date作为一些位置参数。$也是原子运算符的一部分,例如$setand $push。所以,最好避免在 Mongodb 中使用这个特殊字符。

于 2013-01-06T19:04:07.330 回答