0

该文件如下所示。

{
    "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
}
4

2 回答 2

2

增加不存在的字段不是问题,因为对其执行 $inc:1 只会创建它并将其设置为 1 后增量。问题是当您没有与要增加的日期相对应的数组项时。

这里有几种可能的解决方案(不涉及多个步骤来增加)。

一种是使用 score: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})

这将增加分数或插入新记录 score: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 中的上限数组功能来做到这一点),否则在每个图书日的位置有一个单独的图书活动分数跟踪集合会更简单一个单独的文档,而不是将每天的分数嵌入到书籍集合中。

于 2013-06-05T13:16:50.877 回答
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
        },
    ]
}

希望有帮助。

于 2013-06-05T12:15:59.760 回答