ExpressJS and MongooseJS: can I query array values in a subdocument?


I've got a web api written using expressjs and mongoosejs.

The main schema in the app contains a subdocument, permissions, which contains array fields. Those arrays contain ids of users who can perform an action on that document.

I'm trying to limit results of a query on that collection by the values in the read subdocument array field:

Here's the main schema:

var MainSchema = new Schema({
    uri: { type: String, required: false },
    user: { type: String, required: false },
    groups: [String],           
    tags: [String],
    permissions: {
        read: [String],
        update: [String],
        delete: [String]

I want to return documents that have a specific value in the array or where that array is empty.

My code doesn't throw an error, but doesn't limit the results; I still get documents that don't match the given value, and aren't empty.

Here's what I've got:

var MainModel = mongoose.model('MainSchema', MainSchema);

app.get('/api/search', function (req, res) {
    var query = MainModel.find({'uri': req.query.uri }); 

    // This works fine
    if (req.query.groups) {
    else if (req.query.user) {

    // How can I return only documents that match req.query.user or ""?
    query.where('').in([req.query.user, ""]);

    query.exec(function (err, results) {
      if (!err) {
        return res.send(results);
      } else {
        return console.log(err);

I have a hunch that the where clause is not testing the value of each of the elements of against each of the values of the array passed to the in clause.


EDIT: Here's a document that shouldn't be returned, but is (note, array includes a value that's not the current user's ID):

    "user": "",
    "uri": "http://localhost:3000/documents/test",
    "permissions": {
      "delete": [
      "update": [
      "read": [
    "tags": [],
    "groups": [

EDITED: Corrected Model/Schema confusion, which wasn't in my code, but was left out in the copy/paste. Thanks.

Problem courtesy of: Jamie


I have looked for and not found an example of a mongodb/mongoose query that tests either for a specified value in a subdocument array field or an empty array field.

Instead, since I control both the API (which this code comes from) and the client application, I refactored.

I now add one of three where clauses to the query, based on client-side user selection:

if (req.query.mode === 'user') {
else if (req.query.mode === 'group') {
    query.$where(' === 0');
else if (req.query.mode === 'class') {
    query.$where(' === 0');

Thanks for your input, @JohnnyHK.

Solution courtesy of: Jamie


There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.