Javascript MongoDB-$设置为更新或推送数组元素

Javascript MongoDB-$设置为更新或推送数组元素,javascript,node.js,mongodb,mongoose,mongodb-query,Javascript,Node.js,Mongodb,Mongoose,Mongodb Query,在products集合中,我有一个RecentView数组,其中有两个字段viewedBy和VIEWEDATE 在一个场景中,如果我已经有了一个由查看的记录,那么我需要更新它。例如,如果我有这样的数组:- “最新视图”:[ { “查看人”:“abc”, “查看日期”:ISODate(“2014-05-08T04:12:47.907Z”) } ] 用户是abc,因此我需要更新上述内容&如果没有abc的记录,我必须$push 我尝试了以下方法:$set:- db.products.update({

在products集合中,我有一个RecentView数组,其中有两个字段viewedBy和VIEWEDATE

在一个场景中,如果我已经有了一个由查看的
记录,那么我需要更新它。例如,如果我有这样的数组:-

“最新视图”:[
{
“查看人”:“abc”,
“查看日期”:ISODate(“2014-05-08T04:12:47.907Z”)
}
]
用户是
abc
,因此我需要更新上述内容&如果没有
abc
的记录,我必须
$push

我尝试了以下方法:
$set
:-

db.products.update({u id:ObjectId(“536c55bf9c8fb24c21000095”),
{$set:
{“最新视图”:
{ 
查看人:“abc”,
查看日期:ISODate(“2014-05-09T04:12:47.907Z”)
}
} 
}
)

上面的查询将删除数组中的所有其他元素。

实际执行您所说的操作并不是一个单独的操作,但我将详细介绍执行此操作所需的部分,或者介绍其他可能的情况

你要找的部分是接线员。您还需要查询的一部分来“查找”所需数组的元素

db.products.update(
{ 
“_id”:ObjectId(“536c55bf9c8fb24c21000095”),
“recentviews.viewedby”:“abc”
},
{ 
“$set”:{
“最新视图.$.vieweddate”:ISODate(“2014-05-09T04:12:47.907Z”)
}
}
)
因此,
$
代表数组中匹配的位置,因此更新部分知道要更新数组中的哪个项。您可以访问数组中文档的各个字段,或者只指定要在该位置更新的整个文档

db.products.update(
{ 
“_id”:ObjectId(“536c55bf9c8fb24c21000095”),
“recentviews.viewedby”:“abc”
},
{ 
“$set”:{
“最新视图。$”:{
“查看人”:“abc”,
“查看日期”:ISODate(“2014-05-09T04:12:47.907Z”)
}
}
)
如果字段实际上没有更改,并且如果不存在完全相同的数组元素,您只想插入一个新的数组元素,那么可以使用

db.products.update(
{ 
“_id”:ObjectId(“536c55bf9c8fb24c21000095”),
“recentviews.viewedby”:“abc”
},
{ 
$addToSet:{
“最新视图”:{
“查看人”:“abc”,
“查看日期”:ISODate(“2014-05-09T04:12:47.907Z”)
}
}
)
但是,如果您只是想通过一个不存在的单数键值“推送”到一个数组,那么您需要进行更多的手动处理,首先查看数组中的元素是否存在,然后在它不存在的地方进行语句

通过跟踪受更新影响的文档数量,您可以从mongoose方法中获得一些帮助:

Product.update(
{ 
“_id”:ObjectId(“536c55bf9c8fb24c21000095”),
“recentviews.viewedby”:“abc”
},
{ 
“$set”:{
“最新视图。$”:{
“查看人”:“abc”,
“查看日期”:ISODate(“2014-05-09T04:12:47.907Z”)
}
},
功能(错误,未受影响){
如果(numAffected==0){
//文档未更新,因此您可以推送到阵列上
产品更新(
{ 
“_id”:ObjectId(“536c55bf9c8fb24c21000095”)
},
{ 
“$push”:{
“最新视图”:{
“查看人”:“abc”,
“查看日期”:ISODate(“2014-05-09T04:12:47.907Z”)
}
}
},
功能(错误,未受影响){
}
);
}            
}
);
这里唯一需要注意的是,从MongoDB 2.6到早期版本的writeConcern消息中有一些实现更改。由于目前不确定mongoose API如何实际实现回调中
numAffected
参数的返回,这种差异可能意味着什么

在以前的版本中,即使您在初始更新中发送的数据与现有元素完全匹配,并且不需要进行实际更改,那么“修改”金额将作为
1
返回,即使没有实际更新

MongoDB 2.6中的写关注点响应包含两部分。一部分显示修改后的文档,另一部分显示匹配项。因此,虽然匹配项将由匹配现有元素的查询部分返回,但如果实际上不需要更改,则实际修改的文档计数将返回为
0


因此,根据返回号在mongoose中的实际实现方式,在内部更新中使用运算符可能更安全,以确保零影响文档的原因不仅仅是确切的元素已经存在。

您知道这是否与Mongo4.2相同吗?