奇怪的MongoDB行为

时间:2013-07-05 17:12:05

标签: python mongodb

我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这样做以及为什么。

如果有人能帮助我理解,请做。我将永远感激你。

2 个答案:

答案 0 :(得分:1)

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

在第二个选项中,您会采取预防措施来提取一个分数。但是,你仍然无法确保永远成功。假设测验或考试的分数等于家庭作业分数的分数。你也可以拉那一个。除了检查您是否以最低分数进行评估之外,还应检查您所提取的评估是否为家庭作业。

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

答案 1 :(得分:0)

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

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