Toggle boolean value of subdocuments

自作多情 提交于 2019-12-14 04:12:18

问题


i am trying to toggle the boolean value inside an array which is a collection of objects, problem is that field is being triggered for two both objects inside array, and i want to toggle it for a one object only.

Document:

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

Controller:

User.find({_id: req.user._id},'Invitation',function(err,docs) {
    if (err) {
        console.log(err);
    }
        var results = [];

        async.each(docs,function(doc,callback) {

            async.each(doc.Invitation,function(invite,callback) {
                User.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('end'+results);
        });

});

MORE:

ID field inside Invitation array is objectId of person, let's say Bob and David send Invitations, so there are two objects inside Invitation array, that means i have two Invitations from two different person, i.e ( Bob and David) now i want to accept invitation of Bob only, so when i accept invitation of Bob, Accepted field should be triggered as true of Bob object in database, now the results that are shown in below answer have both objects set to true, where i only want accepted invitation to be true.

Same is happening with me when i accept invitation of only one user/person both objects are getting true.


回答1:


I cannot see the result that you claim, which means it works for me and the rest of the world. Here is the abridged listing as a single script example:

    var async = require('async'),
        mongoose = require('mongoose'),
        Schema = mongoose.Schema;

    mongoose.connect('mongodb://localhost/test');

    var invitationSchema = new Schema({
      "ID": { "type": Schema.Types.ObjectId },
      "Accepted": Boolean
    });

    var userSchema = new Schema({
      "Invitation": [invitationSchema]
    });


    var User = mongoose.model( 'User', userSchema );

    User.find({},'Invitation',function(err,docs) {
      if (err) throw err;
      var results = [];

      async.each(docs,function(doc,callback) {
        async.each(doc.Invitation, function(invite,callback) {
          User.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) throw err;
        console.log( results.slice(-1)[0] );
        process.exit();
      });
    });

So that clearly "toggles" both values as requested and works perfectly.

This is the result from me on one shot:

{ _id: 54be2f3360c191cf9edd7236,
  Invitation:
   [ { __v: 0,
       ID: 54afaabd88694dc019d3b628,
       __t: 'USER',
       _id: 54b5022b583973580c706784,
       Accepted: true },
     { __v: 0,
       ID: 54af6ce091324fd00f97a15f,
       __t: 'USER',
       _id: 54bde39cdd55dd9016271f14,
       Accepted: true } ] }


来源:https://stackoverflow.com/questions/28042257/toggle-boolean-value-of-subdocuments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!