MongoDB. Изменить тип из идентификатора объекта

#mongodb

#mongodb

Вопрос:

У меня есть коллекция Shirt, в которой есть поле «Изображения», которое в настоящее время является ссылкой на другую коллекцию:

 ...
    images: {
        type: [{
            type: Schema.Types.ObjectId,
            ref: 'Image'
        }]
    }, 
  

Мне нужно изменить этот тип на объект, подобный этому:

 const ImageSchema = new Schema({
    cloudImage: String,
    imageName: String,
});

 ...
    images: {
        type: ImageSchema
    }, 
  

Проблема: в моей базе данных у меня уже есть около 1000 документов с идентификатором объекта, хранящимся в поле изображения.
Поскольку документов не так много, я решил выполнить цикл по всем документам, преобразовать данные и снова сохранить их в новой структуре модели.
Проблема в том, что когда я получаю «изображения» из «рубашки», mongo возвращает это:

 [ { _bsontype: 'ObjectID',
    id: <Buffer 5f 8a fe 45 0b cc ae 21 5a 9f 2c 6b> } ]
  

И ошибка:

 CastError: Cast to ObjectId failed for value "{ _bsontype: 'ObjectID',
  id: <Buffer 5f 8a fe 45 0b cc ae 21 5a 9f 2c 6b> }" at path "_id" for model "Image"
  

Я предполагаю, что это происходит потому, что хранится идентификатор объекта, и я изменил изображение поля коллекции на другой тип. Если я снова введу [ObjectId] в тип, он вернет идентификатор.

Мой скрипт для выполнения этой операции:

 async function updateShirtImages() {

    const shirts = await Shirt.find({});

    shirts.forEach(async (shirt) => {

        
        const imagesArray = shirt.images;
        console.log(IMAGES ARRAY =>, imagesArray)
        //Result: IMAGES ARRAY ==> [ { _bsontype: 'ObjectID',
        //id: <Buffer 5f 8a fe 45 0b cc ae 21 5a 9f 2c 6b> } ]
         
        imagesArray.forEach(async (image) => {
            console.log(image)
            const databaseImage = await Image.findOne({ _id: image }); // Here the error
            const updatedDataImageShirt = {
                cloudImage: databaseImage.cloudImage,
                imageName: databaseImage.imageName,
            };
            shirt.images.push(updatedDataImageShirt);
            await shirt.save();
        })
    })
}
  

Спасибо!

РЕДАКТИРОВАТЬ ==> Решаемая проблема, применение.lean(), когда я выполняю метод find() во всех рубашках, чтобы получить POJO.

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

1. Можете ли вы распечатать shirt.images , ваша функция findOne ожидает идентификатор объекта, но я считаю, что в это передается что-то еще

2. Я уже отредактировал сообщение, добавив журнал. Он возвращает, что когда я изменил поле, я имею в виду, что в модели оно не является ссылкой (ObjectId) на образ модели, но теперь оно встроено. Для тестирования я снова изменил модель на эталонную, и она вернула ок ObjectId («asdasdas»)

3. Рад, что вы решили свою проблему

Ответ №1:

is valid Перед запросом коллекции изображений проверьте, соответствуют ли изображения ObjectId,

 async function updateShirtImages() {
    try {
        const shirts = await Shirt.find({}).exec();
        for (const shirt of shirts) {
            for (const image of shirt.images) {
                if (image amp;amp; mongoose.Types.ObjectId.isValid(image)) {
                    const databaseImage = await Image.findOne({ _id: image }).exec();
                
                    if (databaseImage !== null) {
                        const updatedDataImageShirt = {
                            cloudImage: databaseImage.cloudImage,
                            imageName: databaseImage.imageName,
                        };
                    
                        shirt.images.push(updatedDataImageShirt);
                        await shirt.save();
                    }
                }
            }
        }
        
    } catch (err) {
        console.error(err);
        throw err;
    }
}
  

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

1. Проверяя это, я избегаю ошибки, но документ не изменяется, поскольку он никогда не попадает в if, потому что он никогда не является допустимым идентификатором объекта, кроме этого [ {_bsontype: ‘ObjectId’, id: <Buffer 5f 8a fe 45 0b cc ae 21 5a 9f 2c 6b> }]

2. @начо, что image ты можешь утешить. записать это?

3. журнал [ { _bsontype: ‘ObjectId’, id: <Buffer 5f 8a fe 45 0b cc ae 21 5a 9f 2c 6b> } ] В базе данных я сохранил его как ObjectId . Но теперь в модели я изменил его на другой тип. Поэтому я думаю, что когда он выполняет функцию find(), он находит не ссылку, а другой тип и возвращает это

4. @nacho это кажется допустимым идентификатором объекта

5. мм, но он не вводится в if… Я сделал несколько logs..is есть ли способ изменить [ { _bsontype: ‘ObjectId’, id: <Buffer 5f 8a fe 45 0b cc ae 21 5a 9f 2c 6b> } ] на фактический понятный для человека идентификатор ?.. например [«5f8afe450bccae215a9f2c6b»]