【问题标题】:How to populate nested objects asynchronously in mongoose?如何在猫鼬中异步填充嵌套对象?
【发布时间】:2016-08-17 07:42:45
【问题描述】:

我正在与猫鼬的人口作斗争。假设我有一个包含许多嵌套对象的大型文档,这些对象并不总是有模式或只是 Type.Mixed。

这个文档的架构应该是这样的:

{
    token: String,
    group: String,
    connectionStatus: String,
    activeQuestLine: String,
    quests:
    {
        exposition: [
            {
                content: { type: mongoose.Schema.Types.ObjectId, ref: 'Quest' },
                status: String,
                trigger:
                {
                    name: String,
                    param: mongoose.Schema.Types.Mixed
                },
                subQuests:
                [
                    {
                        content: { type: mongoose.Schema.Types.ObjectId, ref: 'Quest' },
                        status: String,
                        trigger:
                        {
                            name: String,
                            param: mongoose.Schema.Types.Mixed
                        }
                    }
                ]
            }
        ],
        conflict: [
            {
                content: { type: mongoose.Schema.Types.ObjectId, ref: 'Quest' },
                status: String
            }
        ],
        resolution: [
            {
                content: { type: mongoose.Schema.Types.ObjectId, ref: 'Quest' },
                status: String
            }
        ]
    },
    inventory:
    {
        maxSlots: Number,
        slots: [
            {
                itemType: String,
                content: mongoose.Schema.Types.Mixed,
                empty: Boolean
            }
        ]
    }
};

所以我会“findOne”这种类型的文档一次,保存它,然后在需要时为我的特定用例填充某些部分。据我所知,这个主题的大多数问题是指在操作后保存填充的文档,但我想保持文档原样,只是将(填充的)数据传递给其他函数。

例如,我只想获取 exposition 属性的某个任务的所有“子任务”。那些也可以有他们的“子任务”,是的,应该有一个递归模式,但现在这不是主要问题。问题是我想像这样迭代它:

async.forEachSeries(
   questInfo.subQuests,
   function (subQuestInfo, eachCallback)
   { 
       QuestManager.getQuest(subQuestInfo.content, function (subQuest)
       {
           if (!subQuest) throw 'SubQuest ' + subQuestInfo.content + ' not found';
           subQuestInfo.content = subQuest;
           eachCallback();
       });
   },
   function (err)
   {
       if (err) throw err;
       activeQuests.push(questInfo);
   });

从主文档中提取 questInfo 并作为参数传递给该功能。但在这一行:

subQuestInfo.content = subQuest;

'content' 的值仍然只是 ObjectId,所以是之前的值。我的任务显然没有影响!是一种人工种群尝试,有没有更好的办法解决这个问题?

感谢您的宝贵时间。

【问题讨论】:

    标签: javascript node.js mongodb mongoose mongoose-populate


    【解决方案1】:

    假设您有一个包含 quest.subQuests 成员的 Quest 架构,我会这样:

    Quest.methods.getSubQuests = function(done) {
      var getSubQuestFns = this.subQuests.map(function(subQuest) {
        return QuestManager.getQuest.bind(QuestManager, subQuest.content)
      })
      async.parallel(getSubQuestFns, done)
    }
    
    // get some Quest instance
    quest.getSubQuests(function(err, subQuests) {
      // whatever
    })
    

    (这不会修改原始任务文档。)

    【讨论】:

    • 感谢您的回答。我实际上没有 quest.subQuests,而是 GameClient.quests.exposition[0].subQuests。这可以确保我将描述性任务数据和任务安排及其关系分开。
    • 是的。基本上就是我上面贴的那个。
    猜你喜欢
    • 1970-01-01
    • 2014-07-28
    • 1970-01-01
    • 2020-08-09
    • 2019-01-16
    • 1970-01-01
    • 2018-10-15
    • 1970-01-01
    相关资源
    最近更新 更多