您需要提供多个密钥$set与位置性的$操作员更新两个匹配的密钥。
我更喜欢现代 ES6 的对象操作方式:
let params = { "_id" : "xxxproductid", "name" : "xxx", "img" : "yyy" };
let update = [
{ 'store.products._id': params._id },
{ "$set": Object.keys(params).filter(k => k != '_id')
.reduce((acc,curr) =>
Object.assign(acc,{ [`store.products.$.${curr}`]: params[curr] }),
{ })
}
];
User.update(...update,callback);
这将产生对 MongoDB 的调用 ( withmongoose.set('debug', true)
)打开,所以我们看到请求:
Mongoose: users.update({ 'store.products._id': 'xxxproductid' }, { '$set': { 'store.products.$.name': 'xxx', 'store.products.$.img' : 'yyy' } }, {})
基本上你在哪里接受你的输入params
并提供_id
作为“查询”的第一个参数:
{ 'store.products._id': params._id },
其余部分通过以下方式从对象中获取“键”Object.keys这使得我们可以用它来“过滤”一个“数组”Array.filter()然后传递给Array.reduce将这些键转换为Object
.
在 - 的里面.reduce()我们称之为Object.assign()它将对象与给定的键“合并”,以这种形式生成:
Object.assign(acc,{ [`store.products.$.${curr}`]: params[curr] }),
使用模板语法将“当前”(curr)“key”分配给新的键名称,再次使用ES6 按键分配语法[]:它允许对象文字中的变量名称。
生成的“合并”对象被传回并分配给“根”对象,其中$set
用于更新的密钥,因此“生成的”密钥现在是其子密钥。
我使用数组作为参数纯粹是为了调试目的,但这也允许实际的语法更清晰.update()
使用“传播”...
运算符来分配参数:
User.update(...update,callback);
简洁明了,还有一些您应该学习的用于对象和数组操作的 JavaScript 技术。主要是因为 MongoDB 查询 DSL 基本上是“对象”和“数组”。所以要学会操纵它们。