简体   繁体   中英

Query attribute of nested mongoose object

I have a mongoose (4.8.1) schema called File . Each File belongs to a Workspace. Each Workspace is either private or not private.

So I want to allow a user to look at files in a workspace by checking if the workspace is private or not. My mongoose schemas are:

var File = new mongoose.Schema({
  filename: {
    type: String,
    required: true
  },
  workspaceId: {
    type: String,
    required: true,
    ref: 'Workspace'
  }
});


var Workspace = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  isPrivate: {
    type: Boolean,
    default: true
  },

});

So first off I get all files in the workspace:

File.find({
  workspaceId: workspaceId
})
.exec().then(function(filesDb){

  console.log('filesDb are ', filesDb);

}

I end up with:

[ { __v: 1,
    _id: 589afc46012a0d0e7c3f4e55,
    filename: 'file-1486552134649.txt',
    workspaceId: '589af17765b3bd72213c6fcb' 
} ]

Which is correct (theres only one file in the workspace).

The workspace is not private, so I first populate the workspaceId:

File.find({
    workspaceId: workspaceId
  })
  .populate('workspaceId')
  .exec().then(function(filesDb) {

    console.log('filesDb are ', filesDb);

  })

And i correctly end up with:

 [ { __v: 1,
    _id: 589afc46012a0d0e7c3f4e55,
    filename: 'file-1486552134649.txt',
    workspaceId: 
     { __v: 1,
       _id: 589af17765b3bd72213c6fcb,
       isPrivate: false,
     }     
  } 
]

So now I want to make sure that the files come from a workspace that is not private:

File.find({
    workspaceId: workspaceId
  })
  .populate('workspaceId')
  .find({
    'workspaceId.isPrivate': false
  })
  .exec().then(function(filesDb) {

    console.log('filesDb are ', filesDb);

  })

But filesDb ends up as an empty array.

I tried other things such as changing the find to:

  .find({
    workspaceId: {
       isPrivate: false
    }
  })

But this returns files regardless of if the workspace is private or not.

So how can I query an attribute of a nested object?

Mongoose doesn't support querying by populate d field. You should query all matching File s, populate Workspace and then filter out File s who reference a private Workspace . I'd define a static method for that, for example:

File.statics.findPublicInWorkspace = function(workspaceId) {
  return this.find({
    workspaceId: workspaceId
  })
  .populate('workspaceId')
  .then(function(files) {
    return files.filter(function(file) {
      return !file.workspaceId.private;
    })
  })
};

and then

File.findPublicInWorkspace(workspaceId)
.then(function(filesDb) {
   console.log('filesDb are ', filesDb);
})

Otherwise, as you want to query files that belong to the only one workspace, you can query this workspace first. Then, depending on whether it is public or not, return all its files or empty list respectively.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM