仅在价格或库存发生变化时,我才需要在MongoDB中多次插入/更新price_lastupdate和stock_lastupdate。
重要思想:
输入数据:
productList = [
{
"code": "123",
"stock_id": "CZ01",
"price": 11.2,
"stock": 10
},
{
"code": "124",
"stock_id": "CZ02",
"price": 12.9,
"stock": 9
},
{
"code": "135",
"stock_id": "CZ01",
"price": 9.9,
"stock": 11
},
{
"code": "110",
"stock_id": "CZ02",
"price": 1.7,
"stock": 5
},
];
目标结构(代码+ stock_id是唯一的):
{
"code": "<string>",
"stock_id": "<string>",
"price": <double>,
"price_lastupdate": <date>,
"stock": <int>,
"stock_lastupdate":<date>
}
答案 0 :(得分:0)
背景:
数据模型:
收藏库存:
{
_id: "CZ01"
stock_provider: "ABC",
supplier_id:"SUP1"
}
集合product_items:
{
"code": "<string>",
"stock_id": "CZ01",
"price": <double>,
"price_lastupdate": <date>,
"stock": <int>,
"stock_lastupdate":<date>
}
查询:
code and stock_id
上创建复合唯一索引以维持product_items集合中的唯一性仅在更改价格之前才更新price_lastupdate:创建一个change stream来监视product_items.price的更新以更新product.price_lastupdate的值。 Here is the example:
const mongo = require("mongodb").MongoClient;
mongo.connect("mongodb://localhost:27017/?replicaSet=rs0").then(client => {
console.log("Connected to MongoDB server");
// Select DB and Collection
const db = client.db("mydb");
const collection = db.collection("product_items");
pipeline = [
{
$match: { "fullDocument.price": { $gte: 250 } }
}
];
// Define change stream
const changeStream = collection.watch(pipeline);
// start listen to changes
changeStream.on("change", function(event) {
collection.update({_id:fullDocument}, {$set:{fullDocument.price_lastupdate:fullDocument.price}})
});
});
stock_lastupdate
创建类似的变化流。product_items
集合中插入单个文档。 / li>
code and stock_id
上创建唯一索引在查询的第一部分要格外小心答案 1 :(得分:0)
我与MongoAtlas合作。我解决了使用 trigger 来更新 priceLastUpdate (operation_type:update,event_ordering:true,full_document:false)。
触发功能:
exports = function(changeEvent){
if(changeEvent.updateDescription.updatedFields.price !== undefined){
context.services.get("xxx").db("xxx").collection("product_items")
.findOneAndUpdate({
_id: changeEvent.documentKey._id
},
{
$set:{
price_lastupdate: new Date()
}
}
);
}
};
但是我的multiinsert或multipleupdate问题仍然没有解决。当我使用 findOneAndModify 在350个循环中插入/更新350个项目时,执行时间约为18s。这是不可接受的10000多个项目。
我当前的HTTP服务:
exports = function(payload, response) {
const {data} = payload.query;
const productPrices = JSON.parse(data);
let products = context.services.get("xxx").db("xxx").collection("product_items");
productPrices.forEach(oneProductPrice => {
context.functions.execute("setProductPrice", oneProductPrice);
});
return "OK";
};
我当前的函数 setProductPrice (从HTTP服务调用):
exports = function(product){
let products = context.services.get("xxx").db("xxx").collection("product_items");
products.findOneAndUpdate({
code: product.code,
stock_id: product.stock_id
},
{
$set:{
price: product.price,
},
$setOnInsert:{
code: product.code,
stock_id:product.stock_id,
price_lastupdate: new Date()
}
},
{
upsert: true,
});
};
我搜索了批量插入/更新:
var bulk = db.items.initializeUnorderedBulkOp();
....
但是Mongo Atlas不知道此功能。
有什么主意吗?