Я пытаюсь создать электронную коммерцию с нуля, используя NodeJS, Express и mongoose, следуя этому руководству: https://www.youtube.com/playlist?list=PL55RiY5tL51rajp7Xr_zk-fCFtzdlGKUp, но когда я save()
, программа заканчивает тем, что пишет дубликат всего и сохраняет оригинал.
Я пробовал использовать updateMany()
и insertMany()
, но это не помогло.
Это схема, расположенная в product.js
const schema = new Schema({
imagePath: {type: String, required: true},
title: {type: String, required: true},
description: {type: String, required: true},
price: {type: Number, required: true}
});
module.exports = mongoose.model('Product', schema);
А это в product-seeder.js
const Product = require('../models/product');
const products = [
new Product({
imagePath: 'https://images-na.ssl-images-amazon.com/images/I/41mPFjDCaXL.jpg',
title: 'Gfuel 1',
description: 'Lorem Ipsum',
price: 20
}), ...x4
]
let done = 0;
for (let i = 0; i < products.length; i++) {
products[i].updateOne((err, result) => {
done++;
if (done === products.length) {
exit();
}
});
}
const exit = () => {
mongoose.disconnect();
}
Это отлично работает, если в базе данных ничего нет, но когда я запускаю этот код несколько раз, он продолжает писать одно и то же несколько раз, когда он должен просто сохранять один из каждого объекта, и если я изменяю некоторую информацию, он должен обновлять ее автоматически.
Если вы не хотите, чтобы документы создавались повторно при каждом запуске, вам нужно сделать какой-либо ключ в вашем документе «уникальным». Попробуйте установить «imagePath» в вашей схеме как уникальный, как показано ниже.
const schema = new Schema({
imagePath: {type: String, required: true, unique: true},
title: {type: String, required: true},
description: {type: String, required: true},
price: {type: Number, required: true}});
Если это решило вашу проблему, не могли бы вы принять ответ и проголосовать за него?
Вы должны вызвать save
вместо updateOne
, чтобы ничего не могло быть обновлено, потому что вы не передали действительный ObjectId и, следовательно, нет ссылки на то, что должно быть обновлено.
Читать документы, чтобы понять, что я имею в виду.
Предположим, ваш Product-seeder.js предназначен для хранения продуктов в базе данных. Если вы хотите изменить их, вы должны получить один продукт или набор продуктов из базы данных, изменить их и снова сохранить.
const Product = require('../models/product');
Product.find().exec((err, docs) => {
if (err) return false; // log the error, send it to front-end, etc...
docs.forEach((doc) => {
doc.title = 'New Title here'
doc.save()
})
})
Это должно обновить каждый продукт в вашей базе данных. Теперь все ваши товары должны иметь заголовок «Новый заголовок здесь».
Чтобы получить один документ, используйте findOne
с атрибутом _id
или title
или что-то еще.
Это работает, но если я вручную изменяю документ, он не обновляется. Мне пришлось бы удалить коллекцию и создать ее снова.
Это потому, что вы не загружаете старые документы из базы данных. Вы всегда создаете новые. Чтобы обновить старые, вы должны загрузить их с помощью Product.find()
, как объяснено здесь.
Спасибо!! Но где именно это должно быть Product.find()
? Не могли бы вы указать, что я должен изменить?
Обновил мой пример! Если вы используете что-то вроде expressjs
, вы должны определить новый маршрут POST с параметром id, чтобы определить, какой продукт будет обновлен.
Это исправляет повторение документа, спасибо!!! Теперь мне нужно найти способ автоматически обновлять все