将数组值添加到元素不在数组中的 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 实现这一点。
【问题讨论】:
templateNames
和 defaults
包含什么?
@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的主要内容,如果未能解决你的问题,请参考以下文章