簡體   English   中英

填充后查找 mongoose

[英]Find after populate mongoose

在通過 mongoose 填充后,我在通過文檔內部匹配的值查詢文檔時遇到了一些問題。

我的模式是這樣的:

var EmailSchema = new mongoose.Schema({
  type: String
});

var UserSchema = new mongoose.Schema({
  name: String,
  email: [{type:Schema.Types.ObjectId, ref:'Email'}]
});

例如,我希望所有用戶的 email 類型為“Gmail”。

以下查詢返回空結果:

Users.find({'email.type':'Gmail').populate('email').exec( function(err, users)
    {
      res.json(users);
    });

我不得不求助於過濾 JS 中的結果,如下所示:

users = users.filter(function(user)
        {
          for (var index = 0; index < user.email.length; index++) {
            var email = user.email[index];
            if(email.type === "Gmail")
            {
              return true;
            }
          }
          return false;
        });

有沒有辦法直接從 mongoose 查詢類似的內容?

@Jason Cust已經很好地解釋了它 - 在這種情況下,最好的解決方案通常是改變模式以防止用存儲在單獨集合中的文檔屬性來查詢Users

這是我能想到的最好的解決方案,不會強迫你這樣做(因為你在評論中說過你不能)。

Users.find().populate({
  path: 'email',
  match: {
    type: 'Gmail'
  }
}).exec(function(err, users) {
  users = users.filter(function(user) {
    return user.email; // return only users with email matching 'type: "Gmail"' query
  });
});

我們在這里做的只是填充匹配附加查詢的email.populate()調用中的match選項) - 否則Users文檔中的email字段將設置為null

剩下的就是返回users數組上的.filter ,就像你原來的問題一樣 - 只有更簡單,非常通用的檢查。 正如您所看到的 - email是存在還是不存在。

Mongoose的populate函數不直接在Mongo中執行。 相反,在初始find查詢返回一個文檔集后, populate將在引用的集合上創建一個單獨的find查詢數組,然后將結果合並回原始文檔。 所以基本上你的find查詢試圖使用引用文檔的屬性(尚未提取,因此undefined )來過濾原始結果集。

在這個用例中,將電子郵件存儲為子文檔數組而不是單獨的集合來實現您想要執行的操作似乎更合適。 此外,作為一般文檔存儲設計模式,這是將數組存儲為子文檔有意義的用例之一:有限的大小和很少的修改。

將架構更新為:

var EmailSchema = new mongoose.Schema({
  type: String
});

var UserSchema = new mongoose.Schema({
  name: String,
  email: [EmailSchema]
});

然后以下查詢應該工作:

Users.find({'email.type':'Gmail').exec(function(err, users) {
  res.json(users);
});

除了使用聚合之外,我找不到任何其他解決方案。 會比較麻煩,但我們會使用 Lookup。

https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM