如何在不影响实际文档的情况下修改 Mongoose 中的结果查询?

Posted

技术标签:

【中文标题】如何在不影响实际文档的情况下修改 Mongoose 中的结果查询?【英文标题】:How can I modify the resulting query in Mongoose without affecting the actual document? 【发布时间】:2020-08-18 04:00:39 【问题描述】:

状态(截至 2020 年 5 月 6 日):已解决,请参阅下面确定的答案。

我希望一切都好,尽管我们现在正在经历全球危机。我目前正在做一个学校网络项目,需要渲染分配给我的特定功能。我将 Mongoose 与 Express 和 Handlebars 一起用于模板。请参阅下面随附的模型架构和说明。

collegeModel - 收藏 A

var collegeSchema = new Schema(
    shortName: type: String,  //value that I intend to synchronously query its occurrence with Collection B
    longName: type: String,
    logo: type: String,
    contactUs:
        telNum: type: String,
        faxNum: type: String,
        email: type: String
    ,
    aboutUs: type: Array,
    visionMission: type: String,
    coreValues: type: String,
    goals: type: String,
    founderBio: type: String,
    philosophy: type: String,
    icon: type: String
);

professorModel - 集合 B

var professorSchema = new Schema(
    profNumber: type: Int32,
    college: type: String,    //value to be compared with shortName
    gender: type: String,
    profName: type: String,
    profCourse: type: String
);

伪代码 - 需要实现的逻辑

app.get('/testCount', function(req,res) 
    collegeModel.find().lean().exec(function(err,collegeRes)
        var collegeObject = [];
        collegeRes.forEach(function(document)
            professorModel.countDocuments(college:document.shortName, function(err2,professorCount)
                document.count = professorCount;
                collegeObject.push(document);   //doing a console.log(collegeObject) would return empty objects [].
            );
        );
    );
);

我不知道自己做错了什么,而且我知道 document.count 存在,因为每次我执行 console.log(document.count) 时它都会返回一个值,但是当它被推送时它变成 []。希望你能帮助我实现我的目标。谢谢!

【问题讨论】:

你把console.log(document.count)放在哪里? .countDocuments 操作是异步的,如果您不跟踪计数,您将不知道何时推送最后一个 document。如果您的环境支持,我建议您使用asyc / await 我在第一个);之后添加它 就像我说的,countDocuments 是异步的,你传递一个回调给它,它会稍后执行。当您console.log 时,回调不会被执行。尝试改用async / awaitPromise 嗨@TheeSritabtim,感谢您的帮助!我该怎么做呢?我很抱歉,因为我只是 js 编码和使用 MongoDb/Mongoose 的初学者 【参考方案1】:

您的查询是异步解决的,您必须找到一种方法等待所有查询完成,以确保您拥有所需的所有数据。

解决此问题的一种方法是使用 async/await (Node.js >= 7.6.0)

app.get('/testCount', async function(req, res)  // note the async keyword
  const collegeRes = await collegeModel.find().lean().exec() // .exec() returns a Promise, so you can `await` it.
  const resultPromises = collegeRes.map(async college =>  // arrow function is equivalent to function in this context
    const professorCount = await professorModel.countDocuments( college: college.shortName )
    college.count = professorCount
    return college
  )
  const collegeObject = await Promise.all(resultPromises)
  console.log(collegeObject)
)

使用bluebird 中的Promise.map 更具可读性,或者您也可以使用其他promise 实用程序库

  const collegeObject = await Promise.map(collegeRes, college => 
    const professorCount = await professorModel.countDocuments( college: college.shortName )
    college.count = professorCount
    return college
  )
  console.log(collegeObject)

【讨论】:

你好!您的回答解决了我的问题,并且您能够如此清楚地向我解释。祝你好运!

以上是关于如何在不影响实际文档的情况下修改 Mongoose 中的结果查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 _id 字段但使用多个属性的情况下在 mongoose 中查找子文档

如何在不影响其他帖子类型的情况下修改默认 WP 帖子的 slug?

如何在不创建 Mongoose 模型的情况下将 GraphQL 与 Mongoose 和 MongoDB 一起使用

如何在不覆盖当前数据的情况下更新 Mongoose 中的混合类型字段?

如何在不选择模式配置参数的情况下使用 mongoose 在 MongoDB 模式实例化中的关联数组/对象中执行 foreach?

Firestore - 如何在不真正获取所有文档的情况下找到可以使用查询获取的文档数量? [复制]