该文件如下所示。
{
"title": "Book1",
"dailyactiviescores":[
{
"date": 2013-06-05,
"score": 10,
},
{
"date": 2013-06-06,
"score": 21,
},
]
}
一旦读者打开书籍,每日活动分数就会增加。想到的第一个解决方案是使用“$”来查找目标日期是否有分数,然后处理它。
err = bookCollection.Update(
{"title":"Book1", "dailyactivescore.date": 2013-06-06},
{"$inc":{"dailyactivescore.$.score": 1}})
if err == ErrNotFound {
bookCollection.Update({"title":"Book1"}, {"$push":...})
}
但我不禁想到有没有办法在数组中返回一个项目的索引?如果是这样,我可以使用一个查询来完成工作,而不是两个。像这样。
index = bookCollection.Find(
{"title":"Book1", "dailyactivescore.date": 2013-06-06}).Select({"$index"})
if index != -1 {
incTarget = FormatString("dailyactivescore.%d.score", index)
bookCollection.Update(..., {"$inc": {incTarget: 1}})
} else {
//push here
}
答案 0 :(得分:2)
增加一个不存在的字段不是问题,因为执行$ inc:1只会创建它并将其设置为1后增量。问题是当您没有与要增加的日期对应的数组项时。
这里有几种可能的解决方案(不涉及多个增量步骤)。
一种方法是预先创建数组元素中的所有日期,分数为:0,如下所示:
{
"title": "Book1",
"dailyactiviescores":[
{
"date": 2013-06-01,
"score": 0,
},
{
"date": 2013-06-02,
"score": 0,
},
{
"date": 2013-06-03,
"score": 0,
},
{
"date": 2013-06-04,
"score": 0,
},
{
"date": 2013-06-05,
"score": 0,
},
{
"date": 2013-06-06,
"score": 0
}, { etc ... }
]
}
但是未来走多远?因此,这里的一个选项是“桶” - 例如,“每个月”有一个活动文档,并且在月初之前有一个创建下个月新文档的作业。有点难过。但它会奏效。
其他选项涉及架构的细微变化。
您可以使用包含book,date,activity_scores的集合。然后,您可以使用简单的upsert来增加分数:
db.books.update({title:"Book1", date:"2013-06-02", {$inc:{score:1}}, {upsert:true})
这会增加分数或插入新记录,分数为:1本书和日期,您的收藏将如下所示:
{
"title": "Book1",
"date": 2013-06-01,
"score": 10,
},
{
"title": "Book1",
"date": 2013-06-02,
"score": 1,
}, ...
根据您从实际用例中简化示例的程度,这可能会很好。
另一个选择是坚持使用数组,但切换到使用日期字符串作为你增加的键:
架构:
{
"title": "Book1",
"dailyactiviescores":{
{ "2013-06-01":10},
{ "2013-06-02":8}
}
}
注意它现在是一个子文档而不是数组,你可以这样做:
db.books.update({title:"Book1"}, {"dailyactivityscores.2013-06-03":{$inc:1}})
它将在子文档中添加一个新日期并将其递增,从而产生:
{
"title": "Book1",
"dailyactiviescores":{
{ "2013-06-01":10},
{ "2013-06-02":8},
{ "2013-06-03":1}
}
}
请注意,现在更难以“累加”该书的分数,因此您可以原子地同时更新同一更新语句中的“小计”,无论是全部时间还是仅适用于本月。
但是,继续在这个子文档中添加天数再次成为问题 - 当你几年后仍然存在并且这些书籍文档大量增长时会发生什么?
我怀疑除非您只保留最近N天的活动分数(您可以使用2.4中的上限数组功能),否则为每本书的书籍活动分数跟踪设置单独的收集会更简单-day是一个单独的文件,而不是将每天的分数嵌入到书中的书中。
答案 1 :(得分:1)
根据文件:
$ inc运算符将字段值增加指定的量。 如果该字段不存在,$ inc将字段设置为指定的字段 量。
因此,如果数组项中不存在score
字段,$inc
会在您的情况下将其设置为1,如下所示:
{
"title": "Book1",
"dailyactiviescores":[
{
"date": 2013-06-05,
"score": 10,
},
{
"date": 2013-06-06,
},
]
}
bookCollection.Update(
{"title":"Book1", "dailyactivescore.date": 2013-06-06},
{"$inc":{"dailyactivescore.$.score": 1}})
将导致:
{
"title": "Book1",
"dailyactiviescores":[
{
"date": 2013-06-05,
"score": 10,
},
{
"date": 2013-06-06,
"score": 1
},
]
}
希望有所帮助。