在使用 Mongoose 进行数据库操作时,populate 是一个非常有用的功能,可以用于将相关联的集合的文档一起查询出来,方便进行操作。但是,当涉及到跨数据库查询时,就会出现一些问题。在本篇文章中,我们将会探讨如何解决 Mongoose populate 的跨数据库查询问题。
背景
在使用 Mongoose 时,我们通常会创建多个 Schema,同时在这些 Schema 之间建立关联。例如,我们有一个 User Schema 和一个 Post Schema,其中 User 和 Post 存在一对多的关系。
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ---------- - --- ----------------- ----- ------- ---- ------ --- ----- ---------- - --- ----------------- ------ ------- -------- ------- ------- - ----- ------------------------------- ---- ------ - --- -------------- - - ----- ---------------------- ------------ ----- ---------------------- ----------- --
在上面的代码中,我们使用了 Mongoose 的 populate 功能,用于查询 Post 时同时查询出对应的 User 信息。
Post.find().populate('author').exec((err, posts) => { if (err) { console.log(err); } else { console.log(posts); } });
以上的代码非常简单明了,它会查询 Post 同时查询出对应的 User 信息,并输出结果。
但是,当 User 和 Post 存储在不同的数据库中时,以上的代码就会出现问题。
问题
当 User 和 Post 存储在不同的数据库中时,如果直接使用 populate 的话,就会出现以下错误:
(node:93421) UnhandledPromiseRejectionWarning: MongooseError: Operation `post.find()` buffering timed out after 10000ms
这是因为 Mongoose 会将当前查询的 Schema 的 _id field 和 ref 的集合的 _id field 作为查询条件,但是在跨数据库的情况下,这些条件是无法直接满足的。因此,我们需要找到一种解决方法。
解决方法
要解决这个问题,我们需要进行以下几步操作:
- 手动查询关联集合的文档;
- 获取关联文档的 _id 属性;
- 使用 _id 属性进行关联查询。
以下是完整的代码:
-- -------------------- ---- ------- -- -- ----------- ----- ---- - ----- ------------------------------------------- ---------- ---- ----------- --- -- -- ------- --- -- --- ------ - --------- -- -- -- --- -------- ----------- ------- ------ ------------- ------ -- - -- ----- - ----------------- - ---- - ------------------- - ---
在上面的代码中,我们使用了 MongoDB 的原生驱动程序手动查询了关联的 User 文档,然后获取了 User 的 _id 属性,最后将其用于关联查询 Post。
在实际应用中,我们可能需要将以上的代码封装成一个函数,以便重复使用。以下是一个简单的示例:
-- -------------------- ---- ------- ----- -------- - ----- ------- ----- -- - ----- ---- - ----- ---------------------------------------- ---------- ---- ----------- --- --- -- - --------- ----------- - --- ------ ------ -- ---------------------- ------ -- - -- ----- - ----------------- - ---- - ----- -------- - -------------- -- -------------- ----------- ----------------------------------- -- - -------------------- ---------------- -- - ------------------- -- - ---
在上面的代码中,我们首先定义了一个名为 populate 的函数,该函数会根据给定的 model 和 path 进行查询。然后,在查询结束后,我们将关联文档的 _id 属性替换为关联文档的实际 _id。最后,我们在调用 find() 时进行了一些修改,以便使用 promises 将所有的查询结果一次性输出。
结论
在本篇文章中,我们探讨了如何解决 Mongoose populate 的跨数据库查询问题。首先,我们了解了问题的背景和根本原因。然后,我们介绍了一种解决方法,即手动查询关联集合的文档,获取关联文档的 _id 属性,使用 _id 属性进行关联查询。最后,我们还提供了一个示例代码以便读者更好地理解和使用。
总的来说,解决 Mongoose populate 的跨数据库查询问题并不难,只需要理解其原因并使用正确的方法即可。希望本篇文章对您有所帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/66f7a23cc5c563ced5a51cd6