【发布时间】:2017-02-10 10:47:21
【问题描述】:
正如我所说的in another question,我正在做一个涉及一棵树的项目。
- 树使用父引用,因此每个节点都有其父节点的 id
- 我需要从数据库中自上而下(从根到子)加载树,并用子数组替换父引用(因为客户端需要它们)
- 我选择了这种方法,因为我估计 98% 的操作将在节点上创建/更新(这样我只需在更新时创建 1 个节点,而不是同时更新父节点以将子节点添加到数组)并且只有大约 2% 是读取操作(我只需要读取完整的树,没有读取部分或子树的用例)
树模型是:
const mongoose = require("mongoose");
const Promise = require("bluebird");
mongoose.Promise = Promise;
const Node = require("./node-model");
const TreeSchema = new mongoose.Schema({
root: { type: Schema.Types.ObjectId, ref: 'Node' },
});
还有节点模型:
const mongoose = require("mongoose");
const Promise = require("bluebird");
mongoose.Promise = Promise;
const NodeSchema = new mongoose.Schema({
parent: Schema.Types.ObjectId,
children: [], // to be populated on loading the tree
data: {
d1: String,
//...
}
});
NodeSchema.methods.populateTree = function() {
return this.constructor.find({ parent: this._id }).exec()
.then(function(arrayOfChildren) {
return Promise.each(arrayOfChildren, function(child){
this.children.push(child); // PROBLEM: 'this' is undfined here!
delete child.parent; // delete parent reference because JSON has problems with circular references
return child.populateTree();
});
});
}
另外,还有一个树容器:
const TreeContainerSchema = new mongoose.Schema({
owner: { type: Schema.Types.ObjectId, ref: 'User', required: true },
tree: { type: Schema.Types.ObjectId, ref: 'Tree' },
});
我正在尝试加载完整的树(在他的容器中)以将其作为 JSON 发送回客户端,如下所示:
getTreeContainerById = function(req, res) {
var promise = TreeContainer.
findById(req.params.id).
populate("owner", "name"). // only include name
populate({
path: "tree",
populate: {
path: "root",
populate: "data"
}
}).exec();
promise.then(function(treeContainer){
return treeContainer.tree.root.populateTree()
.then(function(){ return treeContainer });
}).then(function(treeContainer) {
// I need the tree container here to send it back to the client
res.json(treeContainer);
});
};
但是这个实现不起作用。我面临的问题是:
- 在
populateTree模式方法中,我无法通过“this”(未定义)访问当前节点,但我需要以某种方式将子节点添加到数组中 - 如果我尝试使用
child.parent.children.push,这也不起作用,因为我只有父级的 id(在child.parent中)而不是实体(我认为这不是正确的方法从数据库中再次加载) - 在早期版本中,我遇到了问题,即 JSON 在树完全填充之前被发送回客户端,但我认为我通过使用模式方法解决了这个问题
- 一般来说,我不知道这是否是解决我的问题的正确方法(填充子引用并删除我的树中的父引用)或者是否有更合适的解决方案
我希望,我可以把我的问题说清楚。非常感谢任何帮助!
【问题讨论】:
-
“有一些问题” - 你能详细说明吗?
-
@Daniel B 我编辑了我的帖子。如果您仍有任何问题,请提出。
-
this的问题很常见并且很容易解决。见这里(和许多其他人)stackoverflow.com/questions/34930771/…
标签: node.js mongoose tree promise bluebird