2013-07-05 3 views
1

Я начал изучать MongoDB 3 дня назад, и, выполняя упражнение, я получил некоторое неожиданное поведение с сервера.Weird MongoDB Behavior

упражнение попросило написать небольшую программу, чтобы удалить низкий балл домашнего задания из документа, которые имеют следующую структуру (этот документ находится внутри коллекции студентов):

{ 
    "_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 

     } 
    ] 
} 

Во всяком случае, при написании программы I случайно сделал ошибку. Вот программа, которую я написал

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

«Вечно благодарен?» :) Это очень долгое время. Вы уверены, что все документы были удалены? (Сколько их было в коллекции 'students')?'_id' должен был ограничивать его одним документом. И, учитывая, что в коде, который вы указали, нет вставки/обновления, я не вижу, как бы это сделало то, что вы сказали. – WiredPrairie

+0

Да, я уверен, в коллекции студентов было 200 документов, структура коллекции баллов, созданная mongo, такова: {{«_id»: 10, «name»: «Demarcus Audette», «type»: «exam», «score»: 44.654}, {«_id»: 10, «name»: «Demarcus Audette», «type»: «домашняя работа», оценка: 45.456}, ...}, я говорю вам это самая странная вещь, которую я когда-либо видел – Codejunky

+0

Какова структура hw, которую вы передаете removeHW? – innoSPG

ответ

1

Поведение совершенно нормально, так как все данные для данного ученика хранятся в одном документе. Что происходит, так это то, что: каждый документ вашей коллекции имеет минимальный балл для оценки домашней работы типа. Таким образом, каждый документ соответствует критериям и удаляется.

Во втором варианте вы берете на себя обязательство потянуть один балл. Но тем не менее, вы не можете быть уверены, что всегда будете успешны. Скажем, что викторина или экзамен имеют баллы, равные минимальной сумме домашних заданий. Вы также можете потянуть это. В дополнение к проверке того, что вы вытягиваете оценку с помощью оценки min, вы также должны проверить, что оценка, которую вы тянете, является домашней работой типа.

Часть вашего запроса («scores.type»: «домашняя работа») обеспечивает только то, что вы обновляете только ученика, у которого есть минимум один балл в домашней работе. Если есть студент без домашней работы, у вас может быть проблема с мин; Я не знаком с python.

+0

Спасибо за ваш ответ, но я должен указать, что функция min только сравнивает оценки домашних заданий, так как hw (который является списком) содержит только _id ученика и два словаря (которые я вытащил ранее), содержащие домашние задания учеников баллы. – Codejunky

+0

Добро пожаловать. В другом случае вы отлично вычисляете мин. Но так как все баллы находятся в одном и том же массиве, минимальная домашняя работа может оценить результат викторины или экзамена. в этом случае вы их вытащите. Попробуйте добавить документ, который имеет одинаковый балл для всего. – innoSPG

+0

Хорошо, я понимаю, что вы имеете в виду, и я думаю, что вы правы. Еще раз спасибо. – Codejunky

0

MongoDB не будет создавать коллекцию «баллов» в ответ на операцию удаления или обновления. В частности, обновление или удаление из коллекции «учеников» не создаст коллекцию «баллов».

MongoDB создает коллекцию, когда вы вставляете ее в эту коллекцию или добавляете в коллекцию или явно вызываете create_collection.