问题描述
考虑架构:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const EightWeekGamePlanSchema = new Schema({
Week: {
type: Number,
required: true
},
LeadId: {
type: String,
required: true
},
PackageId: {
type: String,
required: true
},
BusinessName: {
type: String,
required: true
},
PhoneNumberMasque: {
type: String,
required: true
},
City: {
type: String,
required: true
},
Rooms: {
type: Number,
required: true
},
LeadStartDate: {
type: Date
},
LeadEndDate: {
type: Date
},
TargetedToBeClaimedByClientType: {
type: Number,
required: true
},
TotalClaimsLeftToBeClaimedByClientType: {
// incresed by 1 every time it's claimed
type: Number,
required: true
},
TotalClaimsToBeClaimedByClientType: {
// Stays fixed
type: Number,
required: true
},
Status: {
type: Number,
required: true
},
InsertDate: {
type: Date,
default: Date.now
}
});
module.exports = EightWeekGamePlan = mongoose.model(
"eightweekgameplan",
EightWeekGamePlanSchema
);
我正在尝试编写一个非常复杂的查询:如果LeadID
出现在给定的数组winnerLeads
中,并且它们的TargetedToBeClaimedByClientType
属性等于给定的groupTarget
,则按howManyClaims
中的给定编号更新多个文档. :
I'm trying the write a pretty complex query : updates multiple documents by given number in howManyClaims
, if their LeadID
appears in a given array winnerLeads
AND their TargetedToBeClaimedByClientType
property equals the given groupTarget
:
router.post("/add-claims-to-group", auth, async (req, res) => {
const { howManyClaims, groupTarget, winnerLeads, week } = req.body;
EightWeekGamePlan.updateMany(
{
LeadId: {
$in: winnerLeads
},
TargetedToBeClaimedByClientType: groupTarget
},
{ $inc: { TotalClaimsToBeClaimedByClientType: howManyClaims } },
{ multi: true },
(err, writeResult) => {
if (err) {
console.log(err);
} else {
console.log(writeResult);
}
}
);
}
否则,执行某种Create
:取属于LeadID
的现有EightWeekGamePlan
文档之一,将其复制并用howManyClaims
设置其TotalClaimsToBeClaimedByClientType
属性.
Otherwise , do some kind of a Create
: take one of the existing EightWeekGamePlan
documents that belong to the LeadID
, duplicate it and set its TotalClaimsToBeClaimedByClientType
property with howManyClaims
.
是否可以在一个查询中结合使用Update和Create动作?
Is it possible to combine both Update and Create actions in one query ?
推荐答案
从您的查询中,由于您正在执行.updateMany()
,因此不必执行{ multi: true }
.无论如何,通常您都可以使用{upset: true}
进行upsert,但是理想情况下,只有在数据库中找不到匹配项的情况下,它才会根据过滤条件以及输入查询中的更新字段来创建新文档.但是,由于我们在过滤条件中有一个列表($in
),因此可能无法正常工作,请尝试以下方法:
From your query, since you're doing .updateMany()
, you don't have to do { multi: true }
. Anyway usually you can do upsert using {upset: true}
, but it would ideally create a new document based on filter criteria with update fields from input query only if no match is found in DB. But since here we're have a list ($in
) in filter criteria it might not work normally, try this :
let winnerLeads = [1, 2, 3, 31, 5]
let groupTarget = 1
let howManyClaims = 2
let bulkArr = []
for (i of winnerLeads) {
bulkArr.push({
updateOne: {
"filter": {
LeadId: i,
TargetedToBeClaimedByClientType: groupTarget
},
// If you wanted it to be incremented rather than replace the field, then try `$inc` instead of `$set`.
"update": { $set: { TotalClaimsToBeClaimedByClientType: howManyClaims } },
"upsert": true
}
})
}
db.EightWeekGamePlan.bulkWrite(bulkArr);
收集数据:
/* 1 */
{
"_id" : ObjectId("5e06eb8f400289966e00fac2"),
"LeadId" : 1,
"TotalClaimsToBeClaimedByClientType" : 1.0,
"TargetedToBeClaimedByClientType" : 1
}
/* 2 */
{
"_id" : ObjectId("5e06eb98400289966e00fb88"),
"LeadId" : 2,
"TotalClaimsToBeClaimedByClientType" : 1.0,
"TargetedToBeClaimedByClientType" : 1
}
/* 3 */
{
"_id" : ObjectId("5e06eba0400289966e00fc47"),
"LeadId" : 3,
"TotalClaimsToBeClaimedByClientType" : 0,
"TargetedToBeClaimedByClientType" : 11
}
/* 4 */
{
"_id" : ObjectId("5e06ebac400289966e00fd4b"),
"LeadId" : 4,
"TotalClaimsToBeClaimedByClientType" : 1,
"TargetedToBeClaimedByClientType" : 11
}
/* 5 */
{
"_id" : ObjectId("5e06ecef400289966e01273a"),
"LeadId" : 5,
"TotalClaimsToBeClaimedByClientType" : 1.0,
"TargetedToBeClaimedByClientType" : 1
}
结果:
/* 1 */
{
"_id" : ObjectId("5e06eb8f400289966e00fac2"),
"LeadId" : 1,
"TotalClaimsToBeClaimedByClientType" : 2.0,
"TargetedToBeClaimedByClientType" : 1
}
/* 2 */
{
"_id" : ObjectId("5e06eb98400289966e00fb88"),
"LeadId" : 2,
"TotalClaimsToBeClaimedByClientType" : 2.0,
"TargetedToBeClaimedByClientType" : 1
}
/* 3 */
{
"_id" : ObjectId("5e06eba0400289966e00fc47"),
"LeadId" : 3,
"TotalClaimsToBeClaimedByClientType" : 0,
"TargetedToBeClaimedByClientType" : 11
}
/* 4 */
{
"_id" : ObjectId("5e06ebac400289966e00fd4b"),
"LeadId" : 4,
"TotalClaimsToBeClaimedByClientType" : 1,
"TargetedToBeClaimedByClientType" : 11
}
/* 5 */
{
"_id" : ObjectId("5e06ecef400289966e01273a"),
"LeadId" : 5,
"TotalClaimsToBeClaimedByClientType" : 2,
"TargetedToBeClaimedByClientType" : 1
}
/* 6 */
{
"_id" : ObjectId("5e071eb1400289966e0597a0"),
"TargetedToBeClaimedByClientType" : 1.0,
"LeadId" : 3.0,
"TotalClaimsToBeClaimedByClientType" : 2.0
}
/* 7 */
{
"_id" : ObjectId("5e071e62400289966e059168"),
"TargetedToBeClaimedByClientType" : 1.0,
"LeadId" : 31.0,
"TotalClaimsToBeClaimedByClientType" : 2.0
}
基本上bulkWrite除了写结果外不返回任何文档,您可以在DB中验证更新操作结果,同样从上述结果中6
插入为LeadId : 3 + TargetedToBeClaimedByClientType" : 1.0
(因此重复了LeadId:3
)组合不是存在于DB&由于数据库中不存在LeadId : 31
,因此已插入7
,其余的1
,2
,5
的TotalClaimsToBeClaimedByClientType
已更新.
Basically bulkWrite doesn't return any documents except write result, you can verify in DB for update operation result, Also from the above result 6
got insert as LeadId : 3 + TargetedToBeClaimedByClientType" : 1.0
(So LeadId:3
is duplicated) combination is not present in DB & 7
got inserted as LeadId : 31
is not present in DB, Remaining 1
,2
,5
's TotalClaimsToBeClaimedByClientType
got updated.
参考: bulkWrite
这篇关于如果存在,则更新许多,否则为每个不存在的LeadId创建一个新文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!