嵌套mongoose对象的查询属性

时间:2017-02-08 12:25:02

标签: javascript node.js mongodb mongoose

我有一个名为File的猫鼬(4.8.1)架构。每个文件都属于一个工作区。每个工作区都是私有的或非私有的。

所以我想让用户通过检查工作区是否是私有来查看工作区中的文件。我的猫鼬模式是:

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
  },

});

首先,我得到工作区中的所有文件:

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

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

}

我最终得到了:

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

哪个是正确的(工作区中只有一个文件)。

工作区不是私有的,所以我首先填充workspaceId:

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

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

  })

我正确地结束了:

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

所以现在我想确保文件来自非私有的工作区:

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

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

  })

filesDb最终为空数组。

我尝试了其他一些事情,例如将find更改为:

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

但无论工作空间是否为私有,都会返回文件。

那么如何查询嵌套对象的属性呢?

1 个答案:

答案 0 :(得分:0)

Mongoose不支持populate d字段的查询。您应该查询所有匹配的File,填充Workspace,然后过滤掉引用私有File的{​​{1}}。我为此定义了静态方法,例如:

Workspace

然后

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

否则,由于您要查询属于唯一一个工作区的文件,因此可以先查询此工作区。然后,根据它是否是公共的,分别返回所有文件或空列表。