惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
博客园 - Franky
罗磊的独立博客
G
Google Developers Blog
The GitHub Blog
The GitHub Blog
P
Proofpoint News Feed
Recent Announcements
Recent Announcements
V
V2EX
F
Fortinet All Blogs
阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
月光博客
月光博客
U
Unit 42
GbyAI
GbyAI
A
About on SuperTechFans
WordPress大学
WordPress大学
Engineering at Meta
Engineering at Meta
雷峰网
雷峰网
Microsoft Azure Blog
Microsoft Azure Blog
Martin Fowler
Martin Fowler
D
DataBreaches.Net
The Cloudflare Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MongoDB | Blog
MongoDB | Blog

Java不加糖的Blog

假设, AI 把我代替的那一刻真的到来 | szhshp 的第三边境研究所 小傻瓜都能懂的 AstrBot QQ 机器人集成 MCP 功能实战指南 | szhshp 的第三边境研究所 《智人之上: 从石器时代到 AI 时代的信息网络简史》阅读笔记 | szhshp 的第三边境研究所 iPadOS 26 无法设置空间场景图片壁纸的解决方法 | szhshp 的第三边境研究所 《一路云海》(终) | szhshp 的第三边境研究所 《一路云海》(四): 如何不按套路旅行 | szhshp 的第三边境研究所 《一路云海》(三): In Ya Mellow Tone | szhshp 的第三边境研究所 《一路云海》(二): 关西世博参观纪实 | szhshp 的第三边境研究所 《一路云海》(一): 新的征程 | szhshp 的第三边境研究所 2025 大阪世博会 [ 3 天前-先到先得 ] 阶段 场馆预约必中独家攻略 | szhshp 的第三边境研究所 Hackathon 随想 | szhshp 的第三边境研究所 一杯双皮奶 | szhshp 的第三边境研究所 Armbian + CasaOS + NAS 配置指南 | szhshp 的第三边境研究所 Docker 构建镜像报错: error getting credentials - err: exit status 1, out: `` | szhshp 的第三边境研究所 Disqus RIP! 论过高的维护成本如何治疗固执的坏习惯 | szhshp 的第三边境研究所 炸弹猫桌游变体规则 | szhshp 的第三边境研究所 《小岛经济学》阅读笔记 | szhshp 的第三边境研究所 《金钱心理学》阅读笔记 | szhshp 的第三边境研究所 为知笔记 RIP: 迁移剩余的笔记 | szhshp 的第三边境研究所 2025 博客第十年展望 - 再见我的过去 | szhshp 的第三边境研究所 我在独立游戏里面致敬的作品 | szhshp 的第三边境研究所 《How to make thing faster》阅读笔记 | szhshp 的第三边境研究所 《The Art of Clean Code》阅读笔记 | szhshp 的第三边境研究所 《Clean Architecture: A Craftsman Guide to Software Structure and Design》阅读笔记 | szhshp 的第三边境研究所 《How AI Works》阅读笔记 | szhshp 的第三边境研究所 游戏策划废案 - Project Uranus | szhshp 的第三边境研究所 游戏策划废案 - Project X | szhshp 的第三边境研究所 人生第一款独立游戏开发复盘 | szhshp 的第三边境研究所 Trap of Life | szhshp 的第三边境研究所 wireguard折腾记录
MongoDB x Mongoose: 实现类似 Join 的功能 | szhshp 的第三...
2019-08-04 · via Java不加糖的Blog

Meta

目录

当前的实现全部都是基于 Mongoose 完成的

官方示例

var mongoose = require('mongoose'),
  Schema = mongoose.Schema

var PersonSchema = new Schema({
  name: String,
  age: Number,
  stories: [{
    type: Schema.Types.ObjectId,
    ref: 'Story'
  }]
});

var StorySchema = new Schema({
  _creator: {
    type: Schema.Types.ObjectId,
    ref: 'Person'
  },
  title: String,
  fans: [{
    type: Schema.Types.ObjectId,
    ref: 'Person'
  }]
});

var Story = mongoose.model('Story', StorySchema);
var Person = mongoose.model('Person', PersonSchema);

var aaron = new Person({
  name: 'Aaron',
  age: 100
});

aaron.save(function(err) {
  if (err) return handleError(err);

  var story1 = new Story({
    title: "Once upon a timex.",
    _creator: aaron._id // assign an ObjectId
  });

  story1.save(function(err) {
    if (err) return handleError(err);
    // thats it!
  });
})

Story
  .findOne({
    title: /timex/
  })
  .populate('_creator')
  .exec(function(err, story) {
    console.log(story)
    if (err) return handleError(err);
    console.log('The creator is %s', story._creator.name); // prints "The creator is Aaron"
  })

自己的例子

Model

ChemListChem 将会引用 Chem 以及 ChemList 两个 Collection

const mongoose = require('mongoose');

const {
  Schema
} = mongoose;

const chemListChemSchema = new mongoose.Schema({
  chemical: {
    type: Schema.Types.ObjectId,
    ref: 'Chem'
  },
  list: {
    type: Schema.Types.ObjectId,
    ref: 'ChemList'
  },
  maxValue: Number,
  minValue: Number,
  active: Boolean,
});

module.exports = mongoose.model('ChemListChem', chemListChemSchema);

Resolver

searchChemListChem: (root, {
  list
}) => ChemListChem.find({
  list: new ObjectId(list)
  // 这个地方很重要,必须生成一个 Object ID
}).populate('list').then((res) => {
  // 然后使用 populate 来获取引用的数据
  console.log(res);
}),

其他

  • 其实不一定要使用 ObjectID 类型来引用
    • Schema.Types.ObjectId 可以根据需要改成其他的类型,但是不推荐
  • 作为 ref 的 field 一定要记得保存成 ObjectID 的模式
  • populate() 对应的 ref field 如果一直返回 null 的话那么就很可能 schema 出错, 可能的错误原因:
    1. ref field 不是 ObjectID 的类型, 保存的时候一定要记得保存成 ObjectID 类型, MongoDB Compass 那边应该看到一个 ObjectID("xxx")
    2. Schema 写错了. 使用 populate() 之前应该返回一个 ID, 使用 populate() 之后应该返回一个 Object