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

时间:2017-06-30 16:11:30

标签: javascript node.js mongodb mongoose mongodb-query

{
   _id:xxxxstoreid
    store:{
        products:[
            {
                _id:xxxproductid,
                name:xxx,
                img:url,
            }
        ]
    }
}

因为我无法预测更新请求,所以params可能只有名称,或者它可能同时具有这两个。

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

var params={_id:xxid,name:'xxx',img:'xxx'}

var params={_id:xxid,name:'xxx'}

在这种情况下如果params只是名称它会删除img字段并更新。

User.update({'store.products._id':params._id},{$set:{"store.products":params}},callback);

3 个答案:

答案 0 :(得分:4)

您需要使用$setpositional $ operator提供多个密钥才能更新两个匹配的密钥。

我更喜欢现代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的调用(启用mongoose.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 key assignment syntax []:

生成的“合并”对象被传回以分配给“根”对象,其中$set用于更新的密钥,因此“生成”密钥现在是其中的子项。

我将一个数组用于纯粹用于调试目的的参数,但是这也允许使用“spread”.update()运算符在实际的...上使用更清晰的语法来分配参数:

User.update(...update,callback);

干净简单,以及一些您应该学习的对象和数组操作的JavaScript技术。主要是因为MongoDB查询DSL基本上是“对象”和“数组”。所以要学会操纵它们。

答案 1 :(得分:2)

find . -type f ! -regex '\./[0-9]+\-[0-9]+/*'

答案 2 :(得分:1)

下面的查询将使用http://www.chromium.org/blink#participating位置运算符来查找在查询文档中通过Observable<Response> responseObservable = ...; Observable<Response> responseWithMinDelay = Observable.concatEager( Observable.timer(1, TimeUnit.SECONDS).ignoreElements(), responseObservable ).cast(Response.class); 匹配数组找到的索引处的数组元素,然后使用{{1更新元素的字段值。

_id