Mongoose中find与findById配合populate返回文档数不一致问题
Mongoose 6.8.4中find()与findById()关联查询结果不一致问题解决
在Mongoose ^6.8.4版本中,即使populate配置完全相同,使用.find()和.findById()查询时,返回的关联文档数量却出现不一致的情况。
Schema定义
NewsSubCategory的Schema中,articles.data字段为NewsArticle的ObjectId数组:
const NewsSubCategorySchema = new Schema<NewsSubCategoryInterface>( { name: { type: String, required: true }, articles: { data: [ { type: Schema.Types.ObjectId, ref: "NewsArticle" } ] } }, { timestamps: true } );
问题复现
使用.find()查询
执行以下查询时,部分子分类的articles.data字段返回指定数量的文章,部分则为空(例如newsArticleLimit设为10时,部分返回10篇,部分无结果):
const subCategoriesData = await NewsSubCategory.find({ _id: { $in: subCategories.data } }) .limit(subCategoriesLimit) .skip(subCategoriesPage * subCategoriesLimit - subCategoriesLimit) .sort({ updatedAt: -1 }) .populate<{ articles: { data: NewsArticleInterface[]; }; }>({ path: "articles.data", select: "some.fields.select", populate: { path: "fields.populate", select: "these fields to populate" }, match: { "relationships.newsAgency.type": { $in: agenciesTypes.data }, "relationships.newsAgency.country": { $in: agenciesCountries.data } }, options: { sort: { createdAt: -1 }, limit: newsArticleLimit, skip: newsArticlePage * newsArticleLimit - newsArticleLimit } })
使用.findById()查询
单独查询某一子分类时,却能正确返回指定数量的关联文章:
let subCategoriesData = await NewsSubCategory.findById(id) .populate<{ articles: { data: NewsArticleInterface[]; }; }>({ path: "articles.data", select: "some.fields.select", populate: { path: "fields.populate", select: "these fields to populate" }, match: { "relationships.newsAgency.type": { $in: agenciesTypes.data }, "relationships.newsAgency.country": { $in: agenciesCountries.data } }, options: { sort: { createdAt: -1 }, limit: newsArticleLimit, skip: newsArticlePage * newsArticleLimit - newsArticleLimit } })
尝试过的无效方案
- 调整
newsArticleLimit参数值 - 检查数据库资源状态
- 逐个查询子分类(性能过低,无法投入使用)
- 移除populate的各类配置(仅移除
limit时查询正常,但速度过慢)
最终解决方案
将populate配置options中的limit替换为perDocumentLimit,即可保证每个子分类都返回指定数量的关联文章:
options: { sort: { createdAt: -1 }, perDocumentLimit: newsArticleLimit, skip: newsArticlePage * newsArticleLimit - newsArticleLimit }
内容的提问来源于stack exchange,提问作者stehvanin
相关产品推荐
相关产品推荐

