Mongoose/node.js how to find, populate, do stuff,

2019-01-29 11:28发布

问题:

I want to make a nice and elegant call to db, but constantly suffer from lack of mongoose experience.

Hope i'm not too annoying, i'm trying to adress Stack Overflow only when my docs-google-Stack-digging skills fails.

What I want to do:

-find a doc in DB
-populate array inside this doc (this array in Schema is an array of Objectids from UserMeta Schema)
-send it throug sockets to some better places
-update found doc with another _id reffering to doc in UserMeta
-save this updates to db & as future reference to var currentroom

Problem occures in last 2 steps, as i can't 'unpopulate' doc, that i already got as response and update-save it further.

For the moment that is how i'm doing this without any population:

Room.findOne({ Roomid: roomid }, function (err, oldRoom) {
    client.emit('others', oldRoom);
    oldRoom.UsersMeta.push(currentUser._id);
    oldRoom.save(function (err, newRoom) {            
        currentroom = newRoom;
    });
})

I can just brute-force-ish copy needed docs through toJSON from parrent UserMeta to this Room doc and just manually maintain both of them. But if there is a way to do this automagically via handy mongoose tools, I would like to take this way. And in the sake of curiosity, of course.

It's a continuation of my previous question Saving reference to a mongoose document, after findOneAndUpdate - just a remark, you dont really need to go there

Upd: Thing is that I need to run populate() In query with findOne, therefore in response I got oldRoom already with populated _ids

Room.findOne({ Roomid: roomid }).populate('UsersMeta').exec(function (err,       oldRoom) {
    if (err) {
        console.log(err);
    }
    else if (oldRoom) {
        console.log(oldRoom.UsersMeta)
        client.emit('others', oldRoom.UsersMeta);
        oldRoom.UsersMeta.push(currentUser._id);
        oldRoom.save(function (err, newRoom) {
            currentroom = newRoom;
            console.log(newRoom);
        });
    }
    else { console.log('nothing found') };
})

upd2: so i figured out, that if i push new _id in already populated oldroom and save it, in db it will automagically appear as set of just _id's as it should be. Yet I now confused if i will continue to work with this currentroom reference, as it was already pupulated, how can i safely remove something from populated array without removing populated entry from db completely.

upd3: Ah i just made a mess in my head. For some weird reason i thought that reference to doc saved in variable for each socket client will be always pointing to up-to-date doc in db, and that i will be able to work with this doc through it elluminating need to using find db tools more than once to get this reference... I need to rethink my db logic.
SO
There is a question then. If user connected to Rooms which is a doc from RoomSchema, and a user is a socket user i.e he has a personal scope in which i can store his personal session details. Can i somehow store direct link to this particular Room doc to elluminate need of searching for this room through whole db if user, for example, changes room's name. If i NEED to searh - it seems that it a better practice to save an id of room in which user is, and then just look up in db for room by this id and change it's name, am I right?

回答1:

Here is the query to get UserMeta with ids only

Room.findOne({ Roomid: roomid },function (err, oldRoom) {

});