I use the library Mongoose v "7.3.4" and i have this type of schemas for my collection
const historicalPrice = new mongoose.Schema({
price: { type: Number, required: true },
time: { type: Date, required: true }
})
const sellers = new mongoose.Schema({
kiabi : { type: [historicalPrice], default: [] },
OVS: { type: [historicalPrice], default: [] },
ZARA: { type: [historicalPrice], default: [] },
});
const listItem = new mongoose.Schema ({
t_shirt: sellers,
shoes: sellers,
hat: sellers,
})
const profile = new mongoose.Schema({
id: { type: String, required: true, unique: true },
date: { type: Date, required: true },
list: { type: listItem, required: true},
})
//the document type
{
id: id,
date: date,
list: {
t_shirt: {
kiabi: [],
OVS: [],
ZARA: []
},
shoes: {
kiabi: [],
OVS: [],
ZARA: []
},
hat: {
kiabi: [],
OVS: [],
ZARA: []
},
},
}
I need an asynchronous function written with Mongoose that takes as parameters an identifying ID of the document, an item, and an object containing the prices of the item for some sellers. This function should update the document by adding an object with the new price and the current date to the historicalPrice array, but only if the new price is different from the previous one; otherwise, it should do nothing. Additionally, if the document is not present, it should create the document with these values.
I tried this code and it works, but it has poor performance.
const newData = {
id: "123456",
item: "t_shirt",
newPrice: {
kiabi: 15,
OVS: 20,
}
}
async function pushData( {id, item, newPrice} ) {
try {
var document = await dataBase.findOne({id: id })
if (document){
for (const seller in newPrice) {
const allPrice = document.list[item][seller]
const l = allPrice.length;
if (l === 0 || allPrice[l-1].price !== newPrice[seller] ){
allPrice.push( { price: newPrice[seller], time: new Date() } )
}
}
await dataBase.replaceOne({ matchName: matchName }, document)
}else{//create new document
var newDocument = {
id: id,
date: new Date(),
list: {
t_shirt: {
kiabi: [],
OVS: [],
ZARA: []
},
shoes: {
kiabi: [],
OVS: [],
ZARA: []
},
hat: {
kiabi: [],
OVS: [],
ZARA: []
},
},
}
for (const seller in newPrice) {
newDocument.list[item][seller].push( { price: newPrice[seller], time: new Date() } )
}
try {
await dataBase.create(newDocument)
} catch (error) {
if (error.code === 11000) {//duplicate key
pushData(id, item, newPrice)//retry
}
}
}
}catch (error){
console.error(error);
}
}
pushData(newData)
I would like to use only Mongoose .updateOne(), but I can't find the correct operators to create a working query.