将数组值添加到元素不在数组中的 MongoDB

Posted

技术标签:

【中文标题】将数组值添加到元素不在数组中的 MongoDB【英文标题】:Add array values into MongoDB where element is not in array 【发布时间】:2019-01-04 01:39:30 【问题描述】:

在 MongoDB 中,这是我的account 文档的简化结构:


    "_id" : ObjectId("5a70a60ca7fbc476caea5e59"),
    "templates" : [ 
        
            "name" : "Password Reset",
            "content" : "AAAAAAAA"
        ,
        
            "name" : "Welcome Message",
            "content" : "BBBBBB"
        
     ]

有一个类似的default_templates 收藏

let accnt = await Account.findOne( _id: req.account._id ,  templates: 1 );
let defaults = await DefaultTemplate.find().lean();

我的目标是在帐户下找到丢失的模板并从默认值中获取它们。 (a) 如果帐户中不存在 templates,我需要对其进行更新,并且 (b) 如果帐户中已存在模板,我不想更新它。

我尝试了以下方法:

if (!accnt.templates || accnt.templates.length < defaults.length) 

  const accountTemplates = _.filter(accnt.templates, 'name');
  const templateNames = _.map(accountTemplates, 'name');

  Account.update( _id: req.account._id, 'templates.name' :  $nin: templateNames  ,
       '$push':  'templates':  '$each' : defaults   ,  'upsert' : true ,
      function(err, result) 
        Logger.error('error %o', err);
        Logger.debug('result %o', result);
      
  );

这在 upsert 中成功,但它会输入所有默认模板,即使 templateNames 中有匹配的名称。我已经验证了 templateNames 数组是正确的,并且我也尝试过使用 $addToSet 而不是 $push,所以我一定不懂 Mongo 子文档查询。

关于我做错了什么有什么想法吗?

编辑:我通过在更新之前简单地从默认数组中删除元素来实现这一点,但我仍然想知道如何使用 Mongoose 实现这一点。

【问题讨论】:

templateNamesdefaults 包含什么? @AnthonyWinzlet defaults 包含与上面显示的 account 相同的文档/模式模板名称包含同一文档上的 name 属性的数组(例如,[ "Password Reset", "Welcome Message" ] upsert 适用于文档级别,而不是子文档。 addToSet 仅在名称和内容相同时才有效(就像不推送)。你的方法是它应该如何工作。 唯一的问题是 $nin 没有做你期望的事情。它仅匹配没有单个模板名称来自 templateNames 的文档,这与“查找丢失的模板”有所不同。 【参考方案1】:

你可以在mongodb中尝试bulkWrite操作

Account.bulkWrite(
  req.body.accountTemplates.map((data) => 
    (
      updateOne: 
        filter:  _id: req.account._id, 'templates.name' :  $ne: data.name  ,
        update:  $push:  templates:  $each : data   ,
        upsert : true
      
    )
  )
)

【讨论】:

以上是关于将数组值添加到元素不在数组中的 MongoDB的主要内容,如果未能解决你的问题,请参考以下文章

PySpark:如何为数组列中的每个元素添加值?

获取值不在数组中的 Firestore 文档

获取值不在数组中的 Firestore 文档

Xcode怎样查看数组中每一个数的值?

php如何删除两个数组中相同的元素

JS六....