{
_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);
答案 0 :(得分:4)
您需要使用$set
向positional $
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