Удаление минимального элемента определенного типа атрибута в MongoDB

У меня есть следующая схема в MongoDB:

{
        "_id" : 100,
        "name" : "John Doe",
        "scores" : [
                {
                        "type" : "exam",
                        "score" : 334.45023
                },
                {
                        "type" : "quiz",
                        "score" : 11.78273309957772
                },
                {
                        "type" : "homework",
                        "score" : 6.676176060654615
                },
                {
                        "type" : "homework",
                        "score" : 35.8740349954354
                }
        ]
}

Я ищу способ удалить домашнее задание с наименьшим количеством баллов. Я нашел связанный ответ здесь, но , это не очень помогает, так как мне нужно найти только «домашнее задание» с наименьшим баллом и удалить его.

Я использую MongoDB вместе с драйвером PyMongo.


person hytriutucx    schedule 09.02.2013    source источник
comment
Кажется, это один из вопросов HW из курса 10gen MongoDB.   -  person akotian    schedule 12.02.2013
comment
@akotian: Срок выполнения домашнего задания уже истек. Вы можете предоставить некоторую помощь/подсказки. Мне не нужно решение.   -  person hytriutucx    schedule 12.02.2013
comment
Кстати, курс повторяется два раза в год в MongoDB University.   -  person tomaskazemekas    schedule 27.10.2015


Ответы (5)


вам нужно добавить match как:

    myresults = scores.aggregate( [ { "$unwind": "$scores" }, { '$match': {'scores.type': "homework" } }, { "$group": { '_id':'$_id' , 'minitem': { '$min': "$scores.score" } } } ] )

    for result in myresults['result']:
        scores.update( { '_id': result['_id'] }, { '$pull': { 'scores': { 'score': result['minitem'] } } } )
person Haim Evgi    schedule 11.02.2013
comment
Я пробовал это в оболочке mongo, но получаю синтаксическую ошибку - не уверен, в чем проблема. ниже приведена ошибка: for result in myresults['result']:scores.update({'_id': result['_id'] }, {'$pull': {'scores': {'score': result[ 'minitem'] } } } ) 2014-11-10T01:14:00.573+0530 SyntaxError: Неожиданный идентификатор - person apratik; 09.11.2014

Я пробовал использовать собственные команды mongodb, и это работает. Используйте приведенные ниже 2 команды, чтобы заставить его работать.

1) курсор = db.students.aggregate([{ "$unwind": "$scores" }, { "$match": { "scores.type": "домашнее задание"}},{ "$group": {' _id': '$_id', 'minitem': {'$min':"$scores.score"}}}]), null

2) cursor.forEach(function(coll) {db.students.update({'_id': coll._id}, {'$pull': {'scores': {'score': coll.minitem}}}) })

person Prabin    schedule 23.08.2015
comment
Первое 1) необходимо изменить следующим образом: cursor = db.students.aggregate([ { $unwind: $scores }, { $match: {scores.type: homework}}, {$group: { '_id': '$_id', 'minitem': {'$min': $scores.score } } } ] ) - person flame3; 05.04.2016

Вот решение с использованием Python:

students = db.students
cursor = students.find({})
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}}})
person tomaskazemekas    schedule 04.11.2015

Я не думаю, что это возможно с использованием собственных команд mongodb. Я думаю, что лучший способ сделать это - написать функцию javascript, чтобы сбросить самый низкий балл и запустить ее на сервере; это имело бы то преимущество, что было бы автоматическим, так что список нельзя было бы обновить, пока вы удаляли из него, сохраняя согласованность.

Вот некоторая документация: http://docs.mongodb.org/manual/applications/server-side-javascript/

person Josh Buell    schedule 09.02.2013

Я следил за третьим ответом здесь. Удаление минимального элемента определенный тип атрибута в MongoDB

    var MongoClient = require('mongodb').MongoClient;

    MongoClient.connect('mongodb://localhost:27017/school', function(err, db) {
      if(err) throw err;

      var students = db.collection('students');
      cursor = students.aggregate(
    [{ "$unwind": "$scores" }, 
     { "$match": { "scores.type": "homework"}},
     { "$group": {'_id': '$_id', 'minitem': {
                    '$min': "$scores.score"
                }
            }
        }

    ]);

    cursor.forEach(
    function(coll) {
        students.update({
            '_id': coll._id
        }, {
            '$pull': {
                'scores': {
                    'score': coll.minitem
                }
            }
        })
    });
    });
person Tommy Rodriguez    schedule 13.06.2015