Найти и удалить документ внутри вложенного массива

#node.js #mongodb #mongoose

#node.js #mongodb #мангуст

Вопрос:

Я изо всех сил пытаюсь удалить элемент внутри вложенного arrray в MongoDB.

Допустим, у меня есть эта схема:

 var question = new Schema({
  problem: {
    type: String,
    required: true
  },
  multipleChoices: [{
    type: String,
    required: true
  }],
  correctAnswer: {
    type: Number,
    required: true
  }
});

var testCategorySchema = new Schema({
  category: {
    type: String,
    required: true
  },
  tests: [{
    version: {
      type: String,
      required: true
    },
    questions: [question]
  }]
});
  

Например, у меня есть экземпляр этой схемы, подобный этому:

 {
  category: "Math",
  tests: [
    {
      _id : ObjectId("580859310a0d4b40ac1c6034"),
      version: "1A",
      questions: [
         {
           problem: "blablabla",
           multiplechoices: [
            "bla bla", "blb blb", "blc blc"
          ],
           correctAnswer: 1
         },
         {
           problem: "blibliblibli",
           multiplechoices: [
            "bla bla", "blb blb", "blc blc"
          ]
           correctAnswer: 1
         }
      ]
    },
    {
      _id : ObjectId("580859310a0d4r40ax1c5034"),
      version: "1B",
      questions: [
         {
           problem: "auauauauau",
           multiplechoices: [
            "bla bla", "blb blb", "blc blc"
          ]
           correctAnswer: 1
         },
         {
           problem: "blibliblibli",
           multiplechoices: [
            "bla bla", "blb blb", "blc blc"
          ]
           correctAnswer: 1
         }
      ]
    }
  ]
}
  

Например, как я могу удалить проблему: «blablabla» в категории math и версии 1A с помощью MongooseJS?

Я уже удалил проблему в категории math и версии 1A, используя этот код:

 TestCategory
    .findOne(
      {
        category: req.params.testCategory,
        'tests.version': req.params.testVersion
      },
      {
        'tests.version.$': 1
      }
    )
    .then(function(testVersion) {
      res.send(testVersion);
    })
    .catch(function(err) {
      console.log(err);
      next(err);
    });
  

Например, я ищу математическую категорию и версию 1A, результат этого кода выглядит следующим образом:

 _id: "580859190a0d4b40ac1c6033",
tests: [
    {
      _id : ObjectId("580859310a0d4b40ac1c6034"),
      version: "1A",
      questions: [
         {
           problem: "blablabla",
           multiplechoices: [
            "bla bla", "blb blb", "blc blc"
          ],
           correctAnswer: 1
         },
         {
           problem: "blibliblibli",
           multiplechoices: [
            "bla bla", "blb blb", "blc blc"
          ]
           correctAnswer: 1
         }
      ]
    }
]
  

Результат уже отфильтрован, поэтому отображается только версия 1A (хотя CategoryID все еще отображается). Теперь я не понимаю, как правильно и качественно удалить вопрос.

Комментарии:

1. Вы уже пробовали что-нибудь для достижения этого?

2. Я уже что-то пробовал, позвольте мне обновить вопрос

3. Обновлено @Shrabanee

Ответ №1:

Вам нужно использовать update с позиционным оператором $ , чтобы обновить правильный тест, а затем использовать $pull для удаления вопроса:

 TestCategory.update(
    {
        category: 'Math',
        'tests.version': '1A'
    },
    {
        $pull: {
            'tests.$.questions': { problem: 'blablabla' }
        }
    }
)
  

Комментарии:

1. $pull: { 'tests.$.questions': { problem: 'blablabla' } }

2. Как я могу удалить его по идентификатору вопроса / проблемы?

3. вы просили удалить по problem значению. в вашей схеме и примере документа у вас нет идентификатора проблемы, так как вы хотите удалить их? если у вас был идентификатор для каждого вопроса, просто замените problem на _id в приведенном выше коде, я не думаю, что мне нужно это объяснять. вам нужно подумать и попробовать самостоятельно, прежде чем задавать подобные вопросы.

4. да, у меня есть идентификатор, потому что в вопросе mongoose это дочерняя схема. Я допустил опечатку при изменении проблемы на идентификатор (typo -> iid). Теперь это работает. Спасибо, чувак

5. вы также можете проголосовать, а не только принять ответ 🙂