[Solved] What is the best way to query data conditionally in MongoDB (node.js)?


To come up with a functioning MongoDB query that determines whether a user is part of a group requires an understanding of how you’re structuring your database and groups collection. One way to structure that is like so:

{
    "_id" : ObjectId("594ea5bc4be3b65eeb8705d8"),
    "group_name": "...",
    "group_members": [
        {
            "user_id": ObjectId("<same one from users collection"), 
            "user_name": "Alice", 
            "user_profile_picture": "<link_to_imag_url>"
        },
        {
            "user_id": ObjectId("<same one from users collection"),
            "user_name": "Bob",
            "user_profile_picture": "<link_to_imag_url>"
        },
        ....
    ]
}

Your group document/object can have attributes for things like it’s name, creation date, description, etc. One of the attributes should be “group_members” which can be used when doing your query to see if a user (based on id) is part of a specific group.

The MongoDB $elemMatch operator seems like a great choice to satisfy your use case (if you’re using a similar group data structure to example one. Further down on that $elemMatch page is a section on Array of Embedded Documents. You can do a query like:

db.groups.find({
    _id: ObjectId("<id of group you're checking"),
    group_members: {
        $elemMatch: { user_id: ObjectId("<user id of user you're checking>") } 
    }
})

That will return either 1 or 0 results. 1 if there is a group with that _id and a group_members array that contains an element that has the user id specified, otherwise 0.

Now to use that in Node, you can use the MongoDB NodeJS Driver in conjunction with an Express web server:

var MongoClient = require('mongodb').MongoClient
var ObjectID = require('mongodb').ObjectID;
var express = require('express');
var app = express();
var bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

// Connection URL
var url="mongodb://localhost:27017/test"; // change test to whichever db you added the collections to

app.get('/partOfGroup', (req, res) => {
    if (req.query.groupId == null || req.query.userId == null) {
        return res.send('Must include both groupId and userId')
    } else {
        MongoClient.connect(url, function(err, db) {
            var collection = db.collection('groups');
            collection.findOne({
                _id: ObjectID(req.query.groupId),
                group_members: {
                    $elemMatch: { user_id: req.query.userId}
                }
            }, function(err, result) {
                return res.send(result != null)
            })
        })
    }
});

app.listen(3000, function () {
    console.log('Example app listening on port 3000');
});

With that up and running, you can go to the url http://localhost:3000/partOfGroup?groupId=594ea5bc4be3b65eeb8705d8&userId=12345 and it should return true or false depending on if there’s a group with id 594ea5bc4be3b65eeb8705d8 and user with id 12345 in that group.

From your front-end code, make a request to that url when a logged in user visits a group page, replacing the group id and user id appropriately. The response you get will determine whether to display a “Join” or “Leave” button.

1

solved What is the best way to query data conditionally in MongoDB (node.js)?