实现类似 Join 的功能
文章目录

MongoDB x Mongoose: 实现类似 Join 的功能

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

官方示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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

1
2
3
4
5
6
7
8
9
10
11
12
13
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

1
2
3
4
5
6
7
8
9
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