Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Querying an array inside a mongoose document

I have 1 - many relationship between users and device (embedded in the user schema)

var UserSchema = new Schema({
    devices: [DeviceSchema] //list of devices for the user      
})

var DeviceSchema = new Schema({
    deviceRegistrationId: String,
    deviceOSType: String
});

I have a Rest calls in express POST /api/device (user id is provided in header) to add devices to user collection, I would like to add device only if the device is not already there in the user model. The body of the post call would something like

{ deviceRegistrationId : "xx2233", 
  deviceOSType: "Android"
}

I check whether or not user id in the header exists in user collection and if it does exist add the device only if the device is not already in the database.

My current implementation is something as follows.

var userId = req.header('UserId');
        var deviceRegistrationId = req.body.deviceRegistrationId;
        User.findById({_id: userId}, function(err, user) {
             if (user && user!==undefined) {
                if (UserController.containsDevice(user.devices, deviceRegistrationId)) {
                    console.log('contains device - do nothing ');
                    res.send({errors: [{code: 666, message: 'Device Already Registered'}]})
                } else {
                    user.devices.addToSet(req.body);
                    user.save();
                    //todo check what to send back.. 
                    res.send(user);
                }
             } else {
                res.send({errors: [{code: 666, message: 'User not found in the database'}]});
             }

             if (err) 
                res.send({errors: [{code: 666, message: 'Unexpected issue in User Collection'}]});
        });


UserController.containsDevice = function(devices, deviceRegistrationId){
        console.log('UserController::containsDevice devices: ' + JSON.stringify(devices) + 
                    " deviceRegistrationId: " + deviceRegistrationId);
        var strDeviceRegistrationId = "" + deviceRegistrationId;
        for (var i = 0; i < devices.length; i++) {
            console.log(' device id :' + JSON.stringify(devices[i].deviceRegistrationId)); 
            if (devices[i].deviceRegistrationId == strDeviceRegistrationId) {
                console.log('id matched');
                return true;
            }
        }

            return false;          

    }

I wanted to check if there was a way not the devices array to determine if the device already existed.

like image 498
rOrlig Avatar asked Jul 17 '13 03:07

rOrlig


People also ask

How do I query an array in MongoDB?

Query an Array by Array LengthUse the $size operator to query for arrays by number of elements. For example, the following selects documents where the array tags has 3 elements.

How do I query nested data in MongoDB?

In MongoDB, you can access the fields of nested/embedded documents of the collection using dot notation and when you are using dot notation, then the field and the nested field must be inside the quotation marks.

How do you find documents with a matching item in an embedded array?

Use $match With $eq to Find Matching Documents in an Array in MongoDB. Use $match With $all to Find Matching Documents in an Array in MongoDB.

How do I filter an array element in MongoDB?

Filter MongoDB Array Element Using $Filter Operator This operator uses three variables: input – This represents the array that we want to extract. cond – This represents the set of conditions that must be met. as – This optional field contains a name for the variable that represent each element of the input array.


1 Answers

You can use dot-separated paths in a query like so: User.find({'devices.deviceRegistrationId': deviceRegistrationId}). If that query doesn't match any documents, no user has that device. Note that mongo is smart enough to test all members of the devices array when given a query such as this. You can also add a user ID to your query conditions if you want to check a specific user.

like image 125
Peter Lyons Avatar answered Sep 23 '22 14:09

Peter Lyons