2015-05-20 58 views
1

我有一個名爲「用戶」貓鼬模式具有「角色」子文檔作爲像這樣的變量之一:如何寫一個貓鼬查詢來篩選子文檔

var UserSchema = new mongoose.Schema({ 
    email: { type: String, required: true, unique: true }, 
    password: { type: String, required: true }, 
    roles: [ { type: Number, ref: 'Role' } ] 
}); 

var RoleSchema = new mongoose.Schema({ 
    _id: Number, 
    name: { type: String, required: true, unique: true }, 
    description: { type: String, required: true } 
}); 

我想創建一個貓鼬查詢它將查找所有role.name爲「admin」或「owner」的用戶。我試過使用這個查詢,我認爲它會起作用,但是當我使用where...in部件時,我沒有得到任何用戶。

var roles = ["owner", "admin"]; 
User.find() 
    .populate('roles') 
    .where('roles.name').in(roles) 
    .sort({'_id': 1}) 
    .exec(function (err, users) { 
     res.send(users); 
    }); 

有人可以告訴我我的邏輯錯在哪?

回答

4

使用單個查詢無法查詢多個集合。如果RoleUser中的嵌入子文檔,那麼您可以在roles.name上執行查詢,但目前不支持,因爲它是User中引用的單獨集合。

但是,解決方法是在查詢返回後添加另一個篩選步驟,手動篩選出沒有任何與填充條件匹配的角色的文檔,但首先您需要在填充中使用匹配查詢,而不是在何處使用方法:

var roles = ["owner", "admin"]; 
User.find() 
    .populate('roles', null, { name: { $in: roles } }) 
    .sort({'_id': 1}) 
    .exec(function (err, users) { 
     users = users.filter(function(user){ 
      return user.roles.length; 
     }); 
     res.send(users); 
    }); 
+1

工作就像一個魅力。太糟糕了,沒有更好的方法來處理這個問題,但這是有效的。謝謝。 –

+0

@JasonAddleman Mongoose爲你想做的事情建立了功能。看到我的答案。 – Rob

+1

@chridam你可以請建議我將如何應用分頁? –

0

這是內置貓鼬populate()here。你可以簡單地構造一個這樣的查詢:

var roles = ["owner", "admin"]; 
User.find() 
    .populate({ 
     path: 'roles', 
     match: { name: { $in: roles }}, 
     select: 'name' 
    }) 
    .sort({'_id': 1}) 
    .exec(function (err, users) { 

     res.send(users); 
    }); 
+2

這會讓我**全部**的用戶,但只有當用戶是所有者或管理員時才填充「角色」字段。這不是我想要的功能。我只想要一個用戶,如果他/她是一個所有者或管理員。這就是爲什麼@ chridam的答案中的過濾器是正確的。 –