任何帮助转换查询链在一个单一的批量指令?



在NodeJs应用程序中,我有一个代码片段:

- check if an element exist (1 query)
- if present, update some value of it (1 query)
- else, add a new record (1 query) and delete an older one (1 query)

所以基本上是4个query for "single"的任务。下面是我的完整代码:

let candleData;
try {
candleData = await Candle.findOne({ instrument_name: instrumentName, exchangeType: exchangeType, dt: dt });
if (!candleData) {
try {
// add new candle
let newCandle = {
instrument_name: instrumentName,
exchangeType: exchangeType,
dt: dt,
o: o,
h: h,
l: l,
c: c
}
await Candle.create(newCandle);
// remove older candle
await Candle.deleteMany({ instrument_name: instrumentName, exchangeType: exchangeType, dt: { $lt: dtOlder } });
} catch (error) {
console.log(error);
return;
}
} else {
// update candle
candleData.c = c;
await candleData.save();
}
} catch (error) {
console.log(error);
return;
}

我可以将其转换为批量操作吗?改善整个链条?

注意:我正在寻找/移除不同的项目。"where"是不同的。对dt=dt求出,对dt小于dtOlder求出。所以这是不一样的。所以它不是upsert指令。

这里有一些文档要做一些测试:

{  "_id": {    "$oid": "62c40373d08fcf4ca03eb4b4"  },  "instrument_name": "BTCBUSD",  "exchangeType": "BINANCE",  "dt": 1657005300000,  "o": "20264.80000000",  "h": "20290.73000000",  "l": "20178.66000000",  "c": "20211.63000000"}
{  "_id": {    "$oid": "62c40373d08fcf4ca03eb4b5"  },  "instrument_name": "BTCBUSD",  "exchangeType": "BINANCE",  "dt": 1657006200000,  "o": "20213.33000000",  "h": "20218.26000000",  "l": "20155.26000000",  "c": "20202.61000000"}
{  "_id": {    "$oid": "62c40373d08fcf4ca03eb4b6"  },  "instrument_name": "BTCBUSD",  "exchangeType": "BINANCE",  "dt": 1657007100000,  "o": "20202.61000000",  "h": "20238.23000000",  "l": "20172.76000000",  "c": "20192.74000000"}
{  "_id": {    "$oid": "62c40373d08fcf4ca03eb4b7"  },  "instrument_name": "BTCBUSD",  "exchangeType": "BINANCE",  "dt": 1657008000000,  "o": "20192.75000000",  "h": "20192.75000000",  "l": "20033.95000000",  "c": "20090.00000000"}
{  "_id": {    "$oid": "62c40373d08fcf4ca03eb4b8"  },  "instrument_name": "BTCBUSD",  "exchangeType": "BINANCE",  "dt": 1657008900000,  "o": "20090.00000000",  "h": "20098.49000000",  "l": "19930.00000000",  "c": "19989.98000000"}

试试这个:

db.candleData.updateOne(
{ instrument_name: instrumentName, exchangeType: exchangeType, dt: dt },
{
$set: { c: c },
$setOnInsert: {
instrument_name: instrumentName,
exchangeType: exchangeType,
dt: dt,
o: o,
h: h,
l: l
}
},
{ upsert: true }
)

确保过滤器只匹配单个文档。

如果您的情况不适合使用upsert,MongoDB Realm FunctionDatabase Trigger
我认为您的逻辑是合理的。

如果需要删除的文档数量为1或0,则可以在一个查询中完成。比如:

  1. $match的共同点。如果这里没有匹配的情况是合理的,则应将此插入$facet
  2. 的两个分支中。
  3. $facet区分found/notFound两种情况。如果找到,替换需要的字段,如果没有,将更新(需要删除)的文档限制为1。
  4. 格式,并使用"deleted"将notFound案例更新为新文档。文档_id。
  5. 使用$ifNull设置一个新的文档更新,根据我们的情况:found/notFound
  6. 使用$merge更新文档(所有情况以一个更新文档结束)。
db.collection.aggregate([
{$match: {instrument_name: instrument_name, exchangeType: exchangeType}},
{
$facet: {
found: [{$match: {dt: dt}}, {$set: {c: c}}],
notFound: [{$match: {dt: {$lt: dtOlder }}}, {$limit: 1}]
}
},
{
$set: {
found: {$first: "$found"},
notFound: {$mergeObjects: [
{$first: "$notFound"}, 
{dt: dt, o: o, h: h, l: l, c: c, instrument_name: instrumentName,
exchangeType: exchangeType}]}
}
},
{$project: {newObj: {$ifNull: ["$found", "$notFound"]}}},
{$merge: {into: "collection"}}
])

看看它在操场的例子中是如何工作的

相关内容

  • 没有找到相关文章

最新更新