#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»]