1

我 3 天前开始学习 MongoDB,在做练习时,我从服务器收到了一些意想不到的行为。

练习要求编写一个小程序,从具有以下结构的文档中删除最低的作业分数(该文档在学生集合中):

{
    "_id": 10,
    "name": "Demarcus Audette",
    "scores": [
        {
            "type": "exam"
            "score": 47.42086

        },
        {
            "type": "quiz"
            "score": 44.83456

        },{
            "type": "homework"
            "score": 39.0178956

        },{
            "type": "homework"
            "score": 14.578344

        }
    ]
}

无论如何,在编写程序时,我不小心犯了一个错误。这是我写的程序

def removeHW(hw):
    # establish a connection to the database
    connection = MongoClient("localhost", 27017)

    # get a handle to the school database
    db = connection.school
    students = db.students

    # extract the scores into a list
    scores = []
    for i in range(1, len(hw)):
        scores.append(hw[i]["score"])

    # Now remove the lowest score from the database
    query = {"_id": hw[0], "scores.score": min(scores),"scores.type": "homework"}

    try:
        students.remove(query)
    except: 
        print "Unexpected error:", sys.exc_info()[0]

我的程序背后的逻辑是,在我从学生集合中提取包含两个作业和 _id 的字典列表后,我遍历每个字典并将其传递给 removeHW() 函数。

我犯的错误是我写道:

query = {"_id": hw[0], "scores.score": min(scores),"scores.type": "homework"}
students.remove(query)

当我应该写以下内容时(这是正确的解决方案):

query = {"_id": hw[0], "scores.type": "homework"}
students.update(query, {"$pull": {"scores": {"score" : min(scores)}}})

是的,我知道直到现在似乎一切都很好。我遇到的问题是,当使用第一个解决方案(错误的解决方案)时,MongoDB 删除了 学生集合中的所有文档,并创建了一个新的集合分数,其中包含学生集合中的所有子文档,除了我想要删除的那个(作业与最低等级)。我发现这种行为非常奇怪,因为我以前没有使用 NoSQL 数据库的经验,所以我想知道是什么导致 MongoDB 这样做以及为什么。

如果有人可以帮助我理解,请做。我会永远感激你。

4

2 回答 2

1

这种行为是完全正常的,因为给定学生的所有数据都存储在同一个文档中。正在发生的事情是:您收藏的每个文档都有一个用于评估类型作业的最低分数。所以每个文档都符合条件并被删除。

在第二个选项中,您采取了拉一分的预防措施。但是,您仍然不能确保总是成功。假设测验或考试的分数等于作业分数的最小值。你也可以拉那个。除了检查您是否以最低分数拉取评估,您还应该检查您拉取的评估是否属于作业类型。

您的查询部分(“scores.type”:“homework”)只是确保您只更新在家庭作业中至少有一个分数的学生。如果有学生没有作业,你可能会遇到 min 的问题;我对python不熟悉。

于 2013-07-05T22:58:56.107 回答
0

MongoDB 不会创建“分数”集合来响应删除或更新操作。特别是,从“学生”集合中更新或删除不会创建“分数”集合。

当您插入到该集合中,或者 upsert 到集合中,或者显式调用 create_collection 时,MongoDB 会创建一个集合。

于 2013-07-09T17:54:27.147 回答