簡體   English   中英

如何使用 mongoose 在循環中迭代 mongoose 返回的文檔數組?

[英]How can i iterate mongoose returned documents array in loop using mongoose?

我有一個node.js(express based)服務器,其中我有一個function返回所有users 這是 function。

export async function findAllUser() {
  let users = await User.find({}).exec()
  return users
}

在我的node.js應用程序中,我有兩個這樣的UsersReferralsmodels(schema)

 var User = mongoose.model( "users", new Schema({ first_name: String, last_name: String, name: String, email: String, password: String, roleId: { type: Number, default: 0 }, country: String, token: String, createdAt: String, updatedAt: String, tempToken: String, verificationCode: String, fbUserId: String, isFbUser: { type: Boolean, default: false }, isActive: { type: Boolean, default: true }, isEmailVerified: { type: Boolean, default: false }, rememberme: Boolean, }, { toJSON: { virtuals: true }, toObject: { virtuals: true } }) ); User.virtual("referrals", { ref: "referralLinks", foreignField: "userId", localField: "_id" });

export var ReferralLink = mongoose.model(
    "referralLinks",
    new Schema({
        referral_link: String,
        referral_code: String,
        isLink: Number,
        offer_name: String,
        offer_desc: String,
        user_email: String,
        companyId: { type: Schema.Types.ObjectId, ref: 'companies' },
        addedByAdmin: { type: Boolean, default: true },
        number_of_clicks: Number,
        referral_country: String,
        link_status: String,
        categoryId: { type: Schema.Types.ObjectId, ref: 'categories' },
        number_of_clicks: { type: Number, default: 0 },
        createdAt: String,
        updatedAt: String,
        userId: { type: Schema.Types.ObjectId, ref: 'users' }
    })
);

我有我單獨的api.route.js文件,其中我有所有用戶這樣的路由

router.get("/", log, getAllUsers);

我的api.controller.js文件有這樣的getAllUsers

export async function getAllUsers(req, res) {
try {
    let Users = await findAllUser()
    if (Users) {
        generateResponse(true, "All Users fetched", Users, res)
    } else {
        generateResponse(false, "No Users found", null, res)
    }
 } catch (err) {
    generateResponse(false, 'Error occured, 404 not found!', err, res)
 }
}

在我的api.handler.js文件中,我有這樣的findAllUser function

 export async function findAllUser() { let users = await User.find({}).populate("referrals").exec() return users }

單個用戶可以擁有多個Referrals人。 但不幸的是,我在Users文檔中沒有“推薦人”參考_id 現在,我想讓所有用戶都有各自的Referrals

我正確地獲得了所有users ,但對於每個用戶,我也想獲取他們各自的referrals 因此,由於 mongoose find 的異步性質,我絕對不能使用forforEach循環。 那么我應該使用什么來代替forforEach循環呢?

我想要的結果

 results = [ { first_name: "Fahad", last_name: "subzwari", email: "fahadsubzwari@gmail.com", password: "***", referrals: [ { //referral object 1 }, { //referral object 2... } ] }, { first_name: "Alex", last_name: "Hales", email: "alex@gmail.com", password: "***", referrals: [ { //referral object 1 }, { //referral object 2... }, { //referral object 3... } ] }, ]

為了能夠訪問用戶的推薦,您需要使用virtual populate

所以你的 userSchema 必須是這樣的:

const userSchema = new Schema(
  {
    first_name: String,
    last_name: String,
    name: String,
    email: String,
    password: String,
    roleId: { type: Number, default: 0 },
    country: String,
    token: String,
    createdAt: String,
    updatedAt: String,
    tempToken: String,
    verificationCode: String,
    fbUserId: String,
    isFbUser: { type: Boolean, default: false },
    isActive: { type: Boolean, default: true },
    isEmailVerified: { type: Boolean, default: false },
    rememberme: Boolean
  },
  {
    toJSON: { virtuals: true },
    toObject: { virtuals: true }
  }
);

// Virtual populate
userSchema.virtual("referrals", {
  ref: "referralLinks",
  foreignField: "userId",
  localField: "_id"
});

var User = mongoose.model("users", userSchema);

現在您可以使用此路由訪問用戶的推薦:

router.get("/", async (req, res) => {

  const result = await User.find({}).populate("referrals");

  res.send(result);
});

結果將是這樣的:(為簡單起見,我排除了一些字段)

[
    {
        "_id": "5dd6819201419f5930d02334",
        "name": "User 1",
        "email": "user1@gmail.com",
        "password": "123123",
        "__v": 0,
        "referrals": [
            {
                "_id": "5dd6829831b95a6b2cd58fca",
                "referral_link": "referral_link 1",
                "userId": "5dd6819201419f5930d02334",
                "__v": 0
            },
            {
                "_id": "5dd682a031b95a6b2cd58fcb",
                "referral_link": "referral_link 2",
                "userId": "5dd6819201419f5930d02334",
                "__v": 0
            }
        ],
        "id": "5dd6819201419f5930d02334"
    },
    {
        "_id": "5dd681a101419f5930d02335",
        "name": "User 2",
        "email": "user2@gmail.com",
        "password": "123123",
        "__v": 0,
        "referrals": [
            {
                "_id": "5dd682a731b95a6b2cd58fcc",
                "referral_link": "referral_link 3",
                "userId": "5dd681a101419f5930d02335",
                "__v": 0
            }
        ],
        "id": "5dd681a101419f5930d02335"
    }
]

更新:

以下是您的項目設置的步驟:

api.handler.js:

exports.findAllUser = async function() {
  console.log("api handler inside");
  let users = await User.find({})
    .populate("referrals")
    .exec();
  console.log("in handler: ", users);
  return users;
};

api.controller.js:

const handler = require("./api.handler");

exports.getAllUsers = async function(req, res) {
  console.log("userController.getAllUsers");
  try {
    let Users = await handler.findAllUser();
    if (Users) {
      return res.send(Users);
      generateResponse(true, "All Users fetched", Users, res);
    } else {
      generateResponse(false, "No Users found", null, res);
    }
  } catch (err) {
    generateResponse(false, "Error occured, 404 not found!", err, res);
  }
};

api.route.js

const apiController = require("../controllers/api.controller");
router.get("/",  log, apiController.getAllUsers);

您說“我在用戶中沒有 'Referrals' 參考 _id”,所以我假設您在 Referrals 架構中有對用戶的參考?

否則,沒有辦法將它們聯系起來,恐怕你會迷失在海上...... :-(

如果你這樣做,那么你會在一個單獨的查詢中這樣做:

const userIds = users.map(user => user._id);

const referrals = await Referrals.find({ userId: { $in: userIds } })

$in 運算符將抓取數組中包含用戶 ID 的任何字段。

編輯:響應您的更新 - 是的,上面應該可以正常工作。 然后你可以用它們做你想做的事情,例如 map 對用戶對象的引用,或者單獨使用它們等等。

EDIT2:是的,這就是方式。 此時,您有一組用戶和一組推薦,因此您只需將它們放在一起。

users.map(user => ({ 
   // add props from user obj
   ...user, 
   // add all referrals that with matching userId
   referrals: referrals.filter(referral => referral.userId === user._id)
 }))

請記住,當您處理異步調用和承諾時,您將需要使用 async/await 關鍵字,或者在 promise 回調中解析結果。

暫無
暫無

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

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