gpt4 book ai didi

javascript - Mongodb 中聚合的更新

转载 作者:可可西里 更新时间:2023-11-01 09:51:34 26 4
gpt4 key购买 nike

我正在尝试切换对象内的 bool 值,这是一个子文档,我很难更新数组内的特定对象。

文档:

"_id" : ObjectId("54afaabd88694dc019d3b628")
"Invitation" : [
{
"__v" : 0,
"ID" : ObjectId("54af6ce091324fd00f97a15f"),
"__t" : "USER",
"_id" : ObjectId("54b4ceb50fc380001bea1752"),
"Accepted" : false
},
{
"__v" : 0,
"ID" : ObjectId("54afac5412f5fdcc007a5c4d"),
"__t" : "USER",
"_id" : ObjectId("54b4cebe0fc380001bea1753"),
"Accepted" : false
}
],

Controller :

User.aggregate([{$match: {_id: ObjectId(54afaabd88694dc019d3b628)}},{$unwind: '$Invitation'},{$project: {_id: '$_id',Invitation: '$Invitation'}}],function(err,results){

function updateInvitation(_id){

var query = {'_id': _id, 'Invitation.ID': ObjectId("54af6ce091324fd00f97a15f")};
var operator = {$inc: {'Invitation.Accepted': 1}};
User.update(query,operator,{multi:true},function(err,updated){
if(err){
console.log(err);
}
console.log('updating'+updated);
});
}
res.jsonp(results);
updateInvitation(results[0]._id);
});

我尝试使用 $set 但没有成功,因为整个 Invitation 数组被替换为“Accepted = 1”如何切换具有特定“ID”的文档的“已接受”字段。

Invitation.$.Accepted

位置运算符不适用于包含数组的字段,因此无法迭代到Accepted 字段

编辑:

User.find({_id: req.user._id},'Invitation',function(err,docs){
if(err){
console.log(err);
}
console.log(docs);
var results = [];
async.each(docs,function(doc,err) {
if(err){
console.log('error'+ err);
}
async.each(docs.Invitation,function(invite,callback) {
console.log('second async');
User.update(
{ '_id': doc._id, 'Invitation._id': invite._id },
{ '$set': {'Invitation.$.Accepted': !invite.Accepted}},
function(err,doc) {
results.push(doc);
console.log('updated'+doc);
callback(err);
}
);
});
},function(err) {
if (err)
console.log(err);
console.log(results);
});

});

控件没有进入第二个 async.each,这里的第一个异步抛出错误是错误:

error-function () {
if (called) throw new Error("Callback was already called.");
called = true;
fn.apply(root, arguments);
}

最佳答案

我真的不认为即使作为馈线查询,聚合框架也不是在这里使用的正确操作。您所做的只是将数组“非规范化”为单个文档。真的应该没有必要。只需获取文档即可:

var query = {}; // whatever criteria

Users.find(query,"Invitation",function(err,docs) {
if (err) {
console.log(err);

var results = [];

async.each(docs,function(doc,callback) {
async.each(docs.Invitation,function(invite,callback) {
Users.findOneAndUpdate(
{ "_id": doc._id, "Invitation._id": invite._id },
{ "$set": { "Invitation.$.Accepted": !invite.Accepted } },
function(err,doc) {
results.push( doc );
callback(err);
}
);
},callback);
},function(err) {
if (err)
console.log(err);

console.log(results);
});

});

因此,在对您正在做的事情的响应中迭代文档列表没有问题,只是您还想迭代数组成员。关键是当发出您需要注意的任何类型的 .update() 时,异步调用就完成了。

所以我正在使用 async.each但你可能想要 async.eachLimit来控制循环。元素的匹配来自positional $运算符,对应查询中匹配的数组元素。

这只是 JavaScript 代码,所以只需使用 !invite.accepted 来“切换”该值即可将其反转。为了获得更多乐趣,通过从 .findOneAndUpdate() 推送修改后的文档返回“结果”数组.

关于javascript - Mongodb 中聚合的更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27960568/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com