我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这样做以及为什么。
如果有人能帮助我理解,请做。我将永远感激你。
答案 0 :(得分:1)
行为完全正常,因为给定学生的所有数据都存储在同一文档中。发生的事情是: 您收藏的每个文件都有一个评分类型作业的最低分数。因此,每个文档都符合标准,并且是删除。
在第二个选项中,您会采取预防措施来提取一个分数。但是,你仍然无法确保永远成功。假设测验或考试的分数等于家庭作业分数的分数。你也可以拉那一个。除了检查您是否以最低分数进行评估之外,还应检查您所提取的评估是否为家庭作业。
您的查询部分(“scores.type”:“家庭作业”)仅确保您只更新在家庭作业中得分最少的学生。如果有学生没有作业,你可能会遇到问题;我不熟悉python。
答案 1 :(得分:0)
MongoDB不会创建“得分”集合来响应删除或更新操作。特别是,更新或删除“学生”集合不会创建“分数”集合。
当您插入到该集合中或嵌入到集合中时,MongoDB会创建一个集合,或者显式调用create_collection。