You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向Mongoose的Campaign.data.actions子数组推送Activity对象?

Got it, let's break down why your current code isn't working and get this fixed properly.

The Issues With Your Current Code

You've got two key problems here that are preventing the update from going through:

  1. filter() returns an array, not a single object: When you run campaign.data.filter(e => e.profileLink === target.profileLink), you're getting an array of matching elements (even if there's only one). Trying to access data.actions either throws an error or does nothing, since arrays don't have an actions property. You need find() instead of filter() to grab the single matching item.
  2. Mongoose can't track deep nested changes: Even if you did get the right data item, directly pushing to actions and calling save() might not trigger Mongoose's change detection for deeply nested objects. It won't recognize the data array was modified, so it skips updating the database.

This is the best approach because it's an atomic database operation (no risk of concurrent updates messing things up) and you don't have to worry about manual change tracking.

Here's how to push the action to the correct actions array in one go:

const updatedCampaign = await Campaign.findOneAndUpdate(
  {
    browserKey: browserKey,
    'data.profileLink': target.profileLink // Match the campaign with the right data element
  },
  {
    $push: {
      'data.$.actions': action // The $ refers to the first matching data element's position
    }
  },
  { new: true } // Optional: returns the updated document instead of the original
);

if (!updatedCampaign) {
  // Handle case where no campaign or matching data element was found
  console.log("Couldn't find the campaign or target data element");
}

If your data array might have multiple elements with the same profileLink (though your schema suggests this shouldn't happen), use arrayFilters to update all matching elements:

const updatedCampaign = await Campaign.findOneAndUpdate(
  { browserKey: browserKey },
  {
    $push: {
      'data.$[elem].actions': action
    }
  },
  {
    arrayFilters: [{ 'elem.profileLink': target.profileLink }],
    new: true
  }
);

Solution 2: Fix Your Original Code

If you prefer to fetch the document first and modify it in code, you need to fix the element lookup and manually trigger change detection:

const campaign = await Campaign.findOne({ browserKey });
if (!campaign) {
  console.log("Campaign not found");
  return;
}

// Find the single matching data element (use find() instead of filter())
const targetDataItem = campaign.data.find(e => e.profileLink === target.profileLink);
if (!targetDataItem) {
  console.log("Target data element not found");
  return;
}

// Push the action to the actions array
targetDataItem.actions.push(action);

// Tell Mongoose the data array was modified (critical for deep nested changes)
campaign.markModified('data');

// Save the updated document
await campaign.save();

Key Notes

  • Always prefer Solution 1 for production code—atomic operations are safer and more efficient.
  • Make sure your action object matches the structure defined in your Activity schema, otherwise Mongoose will reject the update.

内容的提问来源于stack exchange,提问作者tpikachu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:53:49