簡體   English   中英

貓鼬:填充樹,其中父級引用自上而下

[英]Mongoose: Populate a tree with parent referencing top-down

正如我在另一個問題中所述 ,我正在從事一個涉及樹木的項目。

  • 該樹使用父代引用,因此每個節點都具有其父代的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' },
});

和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 ),而不是實體的ID(而且我認為這不是正確的方法)再次從數據庫加載它)
  • 在較早的版本中,我遇到的問題是,在樹完全填充之前,JSON已發送回客戶端,但是我認為我是通過使用schema方法解決了此問題
  • 通常,我不知道這是否是解決我的問題的正確方法(填充子引用並刪除樹中的父引用),或者是否有更合適的解決方案

希望我能闡明我的問題。 任何幫助深表感謝!

使用populateTree如下所示:

NodeSchema.methods.populateTree = function() {
  var node = this;
  return this.constructor.find({ parent: this._id }).exec()
    .then(function(arrayOfChildren) {
      return Promise.each(arrayOfChildren, function(child){
        node.children.push(child);
        child.parent = null;
        return child.populateTree();
      });
    });
}

感謝@danh的建議!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM