Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何用一个请求更新数组对象的多个字段?_Javascript_Node.js_Mongodb_Mongoose_Mongodb Query - Fatal编程技术网

Javascript 如何用一个请求更新数组对象的多个字段?

Javascript 如何用一个请求更新数组对象的多个字段?,javascript,node.js,mongodb,mongoose,mongodb-query,Javascript,Node.js,Mongodb,Mongoose,Mongodb Query,由于我无法预测更新请求,params可能只有名称,也可能两者都有 这是我的查询,它成功更新,但如果参数中不存在其他字段,它会删除这些字段。 例如: 或 在这种情况下,如果参数只有名称,它将删除img字段并进行更新 var params={_id:xxid,name:'xxx'} 下面的查询将使用位置运算符在通过查询文档中的\u id匹配数组找到的索引处定位数组元素,然后使用参数值更新元素的字段 function updateProducts(params) { var query =

由于我无法预测更新请求,params可能只有名称,也可能两者都有

这是我的查询,它成功更新,但如果参数中不存在其他字段,它会删除这些字段。 例如:

在这种情况下,如果参数只有名称,它将删除img字段并进行更新

var params={_id:xxid,name:'xxx'}
下面的查询将使用位置运算符在通过查询文档中的
\u id
匹配数组找到的索引处定位数组元素,然后使用
参数值更新元素的字段

function updateProducts(params) {
    var query = {'store.products': {$elemMatch: {_id: params._id}}}
    var updateObject = null;
    if (params.name && params.img) {
        updateObject = {$set: {'store.products.$': params}}
    } else if(params.name && !params.img) {
        updateObject = {$set: {'store.products.$.name': params.name}}    
    } else if (params.img && !params.name) {
        updateObject = {$set: {'store.products.$.img': params.img}}  
    }

    User.update(query, updateObject, callback)
}
下面的查询将使用位置运算符在通过查询文档中的
\u id
匹配数组找到的索引处定位数组元素,然后使用
参数值更新元素的字段

function updateProducts(params) {
    var query = {'store.products': {$elemMatch: {_id: params._id}}}
    var updateObject = null;
    if (params.name && params.img) {
        updateObject = {$set: {'store.products.$': params}}
    } else if(params.name && !params.img) {
        updateObject = {$set: {'store.products.$.name': params.name}}    
    } else if (params.img && !params.name) {
        updateObject = {$set: {'store.products.$.img': params.img}}  
    }

    User.update(query, updateObject, callback)
}

您需要向提供多个密钥,以更新两个匹配的密钥

我更喜欢现代的ES6对象操作方式:

var params = {_id:1, name:'xxx',img:'yyy'};
var id = params['_id']; // Get id to locate matching array index
delete params['_id']; // Remove id from the object
Object.keys(params).forEach(function (key){params['store.products.$.'+key] = params[key]; delete params[key];}) // Transforms remaining object keys to include the positional $ placeholder to { "store.products.$.name" : "xxx", "store.products.$.img" : "yyy" }

User.update('store.products._id':id},{$set:params},callback);
这将产生对MongoDB的调用,因为(
mongoose.set('debug',true)
)已打开,因此我们可以看到请求:

Mongoose:users.update({'store.products.\u id':'xxxproductid'},{'$set':{'store.products.$.name':'xxx','store.products.$.img':'yyy'},{})

其中,基本上您接受输入
参数
,并提供
\u id
作为“查询”的第一个参数:

其余部分从对象获取“关键点”,通过该对象生成一个“数组”,我们可以使用该数组进行“过滤”,然后传递到以将这些关键点转换为
对象

在我们称之为“合并”对象和给定键的内部,以以下形式生成:

  { 'store.products._id': params._id },
使用模板语法将“current”(curr)“key”分配到新的key名称中,再次使用允许在对象文本中使用变量名的

生成的“合并”对象被传递回指定给“根”对象,其中
$set
用于更新的键,因此“生成的”键现在是该对象的子对象

我使用数组作为参数纯粹是为了调试,但这也允许对实际的
.update()
使用“spread”
操作符分配参数时使用更简洁的语法:

  Object.assign(acc,{ [`store.products.$.${curr}`]: params[curr] }),

简洁明了,还有一些JavaScript技术,您应该学习这些技术来进行对象和数组操作。主要是因为MongoDB查询DSL基本上是“对象”和“数组”。所以要学会操作它们。

您需要提供多个键来更新两个匹配的键

我更喜欢现代的ES6对象操作方式:

var params = {_id:1, name:'xxx',img:'yyy'};
var id = params['_id']; // Get id to locate matching array index
delete params['_id']; // Remove id from the object
Object.keys(params).forEach(function (key){params['store.products.$.'+key] = params[key]; delete params[key];}) // Transforms remaining object keys to include the positional $ placeholder to { "store.products.$.name" : "xxx", "store.products.$.img" : "yyy" }

User.update('store.products._id':id},{$set:params},callback);
这将产生对MongoDB的调用,因为(
mongoose.set('debug',true)
)已打开,因此我们可以看到请求:

Mongoose:users.update({'store.products.\u id':'xxxproductid'},{'$set':{'store.products.$.name':'xxx','store.products.$.img':'yyy'},{})

其中,基本上您接受输入
参数
,并提供
\u id
作为“查询”的第一个参数:

其余部分从对象获取“关键点”,通过该对象生成一个“数组”,我们可以使用该数组进行“过滤”,然后传递到以将这些关键点转换为
对象

在我们称之为“合并”对象和给定键的内部,以以下形式生成:

  { 'store.products._id': params._id },
使用模板语法将“current”(curr)“key”分配到新的key名称中,再次使用允许在对象文本中使用变量名的

生成的“合并”对象被传递回指定给“根”对象,其中
$set
用于更新的键,因此“生成的”键现在是该对象的子对象

我使用数组作为参数纯粹是为了调试,但这也允许对实际的
.update()
使用“spread”
操作符分配参数时使用更简洁的语法:

  Object.assign(acc,{ [`store.products.$.${curr}`]: params[curr] }),

简洁明了,还有一些JavaScript技术,您应该学习这些技术来进行对象和数组操作。主要是因为MongoDB查询DSL基本上是“对象”和“数组”。所以要学会操纵它们。

我不知道你的意思。另外,我忘了提到,
products
字段是一个数组,因此您无法访问它的属性。您的问题需要更详细的信息,比如您所调用的params是什么。在mongoose中,有一种方法可以完成findOne并保存ryt?那么在这种情况下,我该如何做呢?正如u所说,产品是一个数组,我如何知道要更新哪个索引?我应该循环产品并将其与参数匹配吗?我不熟悉mongoose,因此无法回答该部分。如果不确定需要更新数组中的哪个元素,请使用位置运算符更新数组中的元素。我不明白你的意思。另外,我忘了提到,
products
字段是一个数组,因此您无法访问它的属性。您的问题需要更详细的信息,比如您所调用的params是什么。在mongoose中,有一种方法可以完成findOne并保存ryt?那么在这种情况下,我该如何做呢?正如u所说,产品是一个数组,我如何知道要更新哪个索引?我应该循环产品并将其与参数匹配吗?我不熟悉mongoose,因此无法回答该部分。如果不确定需要更新数组中的哪个元素,请使用位置运算符更新数组中的元素。参见[此处]()在提供的答案中是否有您认为无法解决您问题的内容?如果是,请对答案进行评论,以澄清哪些问题需要解决,哪些问题尚未解决。如果它确实回答了您提出的问题,那么请注意您提出的问题,在提供的答案中,您认为有什么东西没有解决您的问题?如果是,请对答案进行评论,以澄清哪些问题需要解决,哪些问题尚未解决。如果它确实回答了您提出的问题,那么请注意您提出的问题
User.update(...update,callback);