Mongoose如何通过ref关联表schemaB的name字段查询schemaA的匹配文档
Mongoose 按关联的schemaB的name字段查询schemaA文档的实现方案
有两种常用的实现方式,可根据数据量场景选择:
方法1:两步查询法(简单易维护,适合中小数据量)
先根据指定的name值查询所有匹配的schemaB文档的_id,再用这些_id查询schemaA:
// 你要匹配的name值 const targetName = '要搜索的name内容' // 第一步:查询所有符合name条件的schemaB的_id const matchedSchemaBList = await SchemaB.find({ name: targetName }, '_id') const matchedIds = matchedSchemaBList.map(item => item._id) // 第二步:查询tag中包含任意符合条件_id的schemaA文档 const result = await SchemaA.find({ tag: { $in: matchedIds } })
特点:逻辑清晰无额外学习成本,debug方便,只要没有超大量的schemaB数据就优先用这种方式。
方法2:单轮聚合查询(适合大数据量场景,减少数据库交互次数)
用MongoDB的$lookup聚合算子直接在数据库层面完成关联查询:
const targetName = '要搜索的name内容' const result = await SchemaA.aggregate([ { $lookup: { *注意:这里的collection名是Mongoose自动将model名转小写加复数后的结果,如果你自定义了collection名请替换成对应值* from: 'schemabs', localField: 'tag', foreignField: '_id', as: 'matched_tag_docs' } }, { // 过滤出关联到的tag文档有匹配name的schemaA记录 $match: { 'matched_tag_docs.name': targetName } } ]) // 如果需要使用schemaA的Mongoose实例方法,可以对结果做hydrate处理 const mongooseDocs = result.map(doc => SchemaA.hydrate(doc))
特点:只需要一次数据库请求,数据量很大的时候性能更好。
注意避坑
不要直接用带match的populate实现这个需求:
// 错误示例:这种写法只会把不符合name条件的tag字段设为null,不会过滤掉不符合的schemaA主文档 const wrongResult = await SchemaA.find().populate({ path: 'tag', match: { name: targetName } })
内容的提问来源于stack exchange,提问作者Mike K
相关产品推荐
相关产品推荐

