$ set и $ pull в MongoDB поверх одного и того же документа

#reactjs #mongodb #express

Вопрос:

у меня есть профиль продукта, и когда я хочу отредактировать продукт, я бы хотел, чтобы пользователь мог редактировать поля в producto (название, цена ….), загружать новое изображение и удалять какое-либо изображение. Все это одновременно, в одной и той же операции.

У меня есть этот код, который работает, но не работает вообще.

 const producto = await Producto.findByIdAndUpdate(
      req.params.id, 
      {
      '$pull': {"images":  {"filename": imagesDelete }}, 
      '$set': {title, categoria, subCategoria, price, description, contacto}},     
      {new: true}
    );
 

с помощью этого кода я могу: загрузить изображение и отредактировать форму, загрузить изображение и удалить какое-либо изображение. Но когда я хочу загрузить изображение, удалить изображение и отредактировать форму. Не работает….
Кто-нибудь может сказать, почему?

Вот полный код в EditProduct:

 exports.editarProductoUser = async (req, res, next) => {
  //REVISAR SI HAY ERRORES
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  console.log(req.body);
  const { imagesDelete, title, categoria, subCategoria, price, description, contacto } = req.body;

  try {
    //   //REVISAR EL ID
    const productoTest = await Producto.findById(req.params.id);

    //   //SI EL PRODUCTO EXISTE O NO!!!
    if (!productoTest) {
      console.log("hay un error en edicion");
      return res.status(404).json({ msg: "Producto no encontrado" });
    }

    // //   //Verificar el PRODUCTO
    if (productoTest.author.toString() !== req.user.id) {
      return res.status(401).json({ msg: "No Autorizado para Editar" });
    }

    if (imagesDelete !== undefined) {
      if (typeof imagesDelete === "string") {
        cloudinary.uploader.destroy(imagesDelete, function (err, res) {
          if (err) {
            console.log(err);
            return res.status(400).json({
              ok: false,
              menssage: "Error deleting file",
              errors: err,
            });
          }
          console.log(res);
        });
      } else {
        for (let filename of imagesDelete) {
          console.log(filename);
          cloudinary.uploader.destroy(filename, function (err, res) {
            if (err) {
              console.log(err);
              return res.status(400).json({
                ok: false,
                menssage: "Error deleting file",
                errors: err,
              });
            }
            console.log(res);
          });
        }
      }
    }

    //ACTUALIZAR PRODUCTO
    const producto = await Producto.findByIdAndUpdate(
      req.params.id, 
      {
      '$pull': {"images":  {"filename": imagesDelete }}, 
      '$set': {title, categoria, subCategoria, price, description, contacto}},     
      {new: true}
    );

    
    const images = req.files.map((f) => ({
      url: f.path,
      filename: f.filename,
    }));

    //if(producto.images === undefined) return null;
    producto.images.push(...images);
    console.log(producto.images);

    await producto.save();
    res.json({ producto });
  } catch (error) {
    console.log(error);
    res.status(500).send("Hubo un Error");
  }
};
 

Вот снимок формы, чтобы увидеть поля:

Редактировать продукт формы

Ответ №1:

$pull и $set

 db.collection.update({
  _id: "123"
},
{
  "$pull": {
    images: {
      filename: "123"
    }
  },
  "$set": {
    title: "banana",
    categoria: "b",
    price: 200
  }
})
 

mongoplayground

nodejs mongoose

 let query = {
  _id: "123"
};
let update = {
  "$pull": {
    "images": {
      "filename": "123"
    }
  },
  "$set": {
    "title": "banana",
    "categoria": "b",
    "price": 200
  }
};

Producto.updateOne(
  query, 
  update, 
  function(err, result) {     
    if (err) {
      ...   
    } else {
      ...
    }
  }
);
 

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

1. Спасибо за ваш ответ, но в этом случае, как вы определяете документ, который хотите обновить? мне не нужно передавать идентификатор продукта? тогда не обязательно использовать {new: true} ? Если я использую этот запрос {}, я обновлю все документы в коллекции … не так ли? В NodeJS. Этот метод не поддерживается!!!

2. Я обновляю свой ответ

3. Спасибо за ваше обновление, все еще не работает, не редактирует мою форму и не отправляет мои новые изображения. спасибо за ваше время

4. Я попробовал еще раз, и не работает. Я не понимаю, почему: const producto = await Producto.findByIdAndUpdate( req.params.id , { ‘$pull’: {«images»: {«filename»: imagesDelete }}, ‘$set’: {заголовок, категория, подкатегория, цена, описание, контакты}},{new: true} ); не работает одновременно.