2015-04-03 2 views
-1

В школе дБ 200 документов. Я должен удалить каждый документ, который имеет «тип»: «домашнее задание» и самый низкий балл.Сравнить элементы массива, удалить тот, который имеет самый низкий балл

{ 
     "_id" : 0, 
     "name" : "aimee Zank", 
     "scores" : 
     [ 
      { 
       "type" : "exam", 
       "score" : 1.463179736705023 
      }, 
      { 
       "type" : "quiz", 
       "score" : 11.78273309957772 
      }, 
      { 
       "type" : "homework", 
       "score" : 6.676176060654615 
      }, 
      { 
       "type" : "homework", 
       "score" : 35.8740349954354 
      } 
     ] 
    } 

Например, здесь

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

должны быть удалены, как оценка = 6,6 < 35,8

Я отсортирован все документы, как это:

db.students.find({"scores.type":"homework"}).sort({"scores.score":1}) 

Но я не знаете, как тогда удалить документ с самым низким счетом и типом: домашнее задание ??? ПРИМЕЧАНИЕ: как решить проблему, не используя метод агрегирования? Например, путем сортировки, а затем обновления.

ответ

0

Это может быть сделано в несколько шагов. Первый шаг, чтобы захватить список документов с минимальным счетом, используя структуру агрегации с $match, $unwind и $group операторов, который упрощает ваши документы, чтобы найти минимальное количество баллов для каждого документа:

lowest_scores_docs = db.school.aggregate([ 
    { "$match": {"scores.type": "homework"} }, 
    { "$unwind": "$scores" }, { "$match": {"scores.type": "homework"} }, 
    { "$group": { "_id":"$_id", "lowest_score": {"$min": "$scores.score" } } } ]) 

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

for result in lowest_scores_docs["result"]: 
    db.school.update({ "_id": result["_id"] }, 
     { "$pull": { "scores": { "score": result["lowest_score"] } } }) 
+0

Привет, Chridam. Я благодарен вам за ваш быстрый ответ. Но, к сожалению, он также не удалял элемент массива с «типом»: «домашнее задание» и наименьшее значение в каждом _id., В каждом документе. –

+0

@sapio_l Отображаются любые сообщения об ошибках? Пробовали ли вы распечатать объект 'lower_scores_docs', чтобы узнать, возвращается ли что-либо из агрегации? – chridam

+0

Да, да. Цикл не работает, он ничего не печатает. @chridam –

0
import pymongo 
import sys 

# connnecto to the db on standard port 
connection = pymongo.MongoClient("mongodb://localhost") 

db = connection.school   # attach to db 
students = db.students  # specify the colllection 


try: 

     cursor = students.find({}) 
     print(type(cursor)) 
     for doc in cursor: 
      hw_scores = [] 
      for item in doc["scores"]: 
       if item["type"] == "homework": 
        hw_scores.append(item["score"]) 
      hw_scores.sort() 
      hw_min = hw_scores[0] 
      #students.update({"_id": doc["_id"]}, 
      #   {"$pull":{"scores":{"score":hw_min}}}) 


except: 
    print ("Error trying to read collection:" + sys.exc_info()[0])