Node.js MongoDB$addToSet到对象的深层嵌套数组
下面是我的数据结构Node.js MongoDB$addToSet到对象的深层嵌套数组,node.js,mongodb,mongoose,mongodb-query,Node.js,Mongodb,Mongoose,Mongodb Query,下面是我的数据结构 { "_id" : "room1", "members" : [ { "_id" : "member1", "name" : "Michael", "payments" : [ { "month": "2018/09" "amount": "20"
{
"_id" : "room1",
"members" : [
{
"_id" : "member1",
"name" : "Michael",
"payments" : [
{
"month": "2018/09"
"amount": "20"
}
]
},
]
}
我想把下面的对象推到Michael的付款
{
"month": "2018/09",
"amount": "5000"
}
在本例中,我想覆盖对象,因为month:“2018/09”
已经存在。如下图所示:
{
"_id" : "room1",
"members" : [
{
"_id" : "member1",
"name" : "Michale",
"payments" : [
{
"month": "2018/09"
"amount": "5000"
}
]
},
]
}
而且,如果我想在payments中推送不存在相同月份
的对象,我想将此对象添加到payments
{
"month": "2018/10",
"amount": "2000"
}
因此,预期的结果是
{
"_id" : "room1",
"members" : [
{
"_id" : "member1",
"payments" : [
{
"month": "2018/09"
"amount": "5000"
},
{
"month": "2018/10"
"amount": "2000"
}
]
},
]
}
我像下面那样试过,但不起作用。我的代码每次尝试时都会生成重复的新
month
对象。我怎样才能正确地做到这一点
Rooms.update(
{
_id: "room1",
"members._id": "member1",
"members.$.payments": {
$not: {
$elemMatch: {
month: req.body.month
}
}
}
},
{
$addToSet: {
"members.$.payments": {
month: req.body.month,
amount: req.body.value
}
}
},
{ multi: true }, function (err, result) {
console.log(result)
}
)
您可以使用下面的命令在月份或金额内不重复地添加
Rooms.update(
{
_id: "room1",
"members._id": "member1"
},
{
$addToSet: {
"members.$.payments": {
month: req.body.month,
amount: req.body.value
}
}
},function (err, result) {
console.log(result)
}
)
所以我听说我必须自己确定复制,下面是我的代码。。。现在正在写
最后这是我的代码
Clubs.findOne({
uid: req.params.club_id,
"members._id": mongoose.Types.ObjectId(req.params.member_uid)
}, function(err, club){
let member = club.members.filter(el => {
if(el._id.equals(req.params.member_uid)) return el
})
let duplicated = false;
member[0].payments.map(el => {
if(el.month === req.body.month) duplicated = true
})
if(duplicated){
Clubs.update(
{
uid: req.params.club_id,
"members._id": mongoose.Types.ObjectId(req.params.member_uid),
},
{
$set: {
["members.$.payments."+index+".amount"] : req.body.value
}
},
function (err, result, third) {
if (err) throw err
console.log('result')
console.log(result)
res.json({})
}
)
} else {
Clubs.update(
{
uid: req.params.club_id,
"members._id": mongoose.Types.ObjectId(req.params.member_uid),
},
{
$push: {
"members.$.payments" : {
month : req.body.month,
amount: req.body.value
}
}
},
function (err, result, third) {
if (err) throw err
console.log('result')
console.log(result)
res.json({})
}
)
}
})
也许考虑<强>将嵌套数组的结构< /强>更改为<强>对象< /强>?所以改变这个
{
"payments": [{
"month": "2018/09"
"amount": "5000"
},
{
"month": "2018/10"
"amount": "2000"
}
]
}
为此:
{
"payments": {
"2018/09": "5000",
"2018/10": "2000"
}
}
然后,您可以执行一个简单的更新:
Rooms.update({
_id: "room1",
"members._id": "member1",
"members.payments": {
$exists: true
}
}, {
$set: {
"members.payments." + req.body.month: req.body.value
}
},
)
在此处使用
$ne
而不是$not
“members.$.payments:{$elemMatch:{month:{$ne:req.body.month}}}
在成员中去掉$。$.payments
在查询部分。@AnthonyWinzlet我加上了你们的建议,但仍然不起作用。。。它不再生成重复的对象,但不会被覆盖。@Veeram谢谢,我删除了它。但它仍然不起作用——不再有重复的对象,但没有被覆盖,正如预期的那样$addToSet不会覆盖元素。你有没有回答我的问题。。。你的回答将生成重复的对象。不,不是我在本地检查过的。这与Juntae在其原始帖子中所写的相同。这导致错误“位置运算符未从查询中找到所需的匹配项”。