mongoose 使用 $in 并且只用最近的时间戳更新一个
Posted
技术标签:
【中文标题】mongoose 使用 $in 并且只用最近的时间戳更新一个【英文标题】:mongoose using $in and only update one with most recent timestamp 【发布时间】:2018-11-19 12:16:05 【问题描述】:不确定这是否可能,但是,
我的集合中很少有documents
。 documents
有重复,唯一的区别是timestamp
例如:
name: 'abc',
verified: false,
createdAt: 'timestamp1'
,
name: 'abc',
verified: false,
createdAt: 'timestamp2'
,
name: 'abc',
verified: false,
createdAt: 'timestamp3'
,
name: 'eee',
verified: false,
createdAt: 'timestamp1'
,
name: 'eee',
verified: false,
createdAt: 'timestamp2'
可以看到,name
字段有重复项,但我只想更新最新的 timestamp
、verified
到 true
但是timestamp
真的很随意。
我可以使用update and $in
,但这将更新所有文档,而不仅仅是最新的timestamp
文档
mongoose 创建的时间戳示例
,
"updatedAt":
"$date": "2018-06-08T23:39:49.310Z"
,
"createdAt":
"$date": "2018-06-08T23:21:15.669Z"
,
这是我使用$in
的简单代码
const names = ['abc', 'eee'];
Model.update(
'name':
$in: names
, verified: true , multi: true );
提前感谢您的帮助。
【问题讨论】:
你的时间戳是哪种类型的?它真的是一个日期还是只是一个字符串? @MatthiasHerrmann 我用时间戳示例更新了我的帖子。时间戳由猫鼬自己创建,架构中带有timestamp: true
换一种说法:在数据库中查找所有具有特定名称的条目,并将verified
和multi
设置为该名称最近创建的条目为true
@MatthiasHerrmann 是的,这是正确的,感谢您的重新定位
【参考方案1】:
通过createdAt
查找指定名称的最新文档:
const names = ['abc', 'eee'];
collection.aggregate(
[
$match: 'name': $in: names,
$group: _id: '$name', createdAt: $max: '$createdAt',
]);
将查询结果保存在变量result
中为Array
或cursor
。
然后你就可以更新文档了:
results.forEach((newestDocumentForName) => collection.update(_id: newestDocumentForName['_id'], /*your set operation*/);
【讨论】:
这个$group: _id: '$name', dates: $max: '$createdAt',
不应该是$group: name: '$name', createdAt: $max: '$createdAt',
吗?
不,name: '$name'
会抛出错误 - 因为它不知道要为 name
选择哪个值以及按什么分组。错误消息听起来像这样:“字段'names'必须是一个累加器对象”
在这种情况下,我将按名为 name
的字段进行分组 - 因此此阶段中的 _id
设置为 $name
。有关分组的文档,请阅读:docs.mongodb.com/manual/reference/operator/aggregation/group/…
谢谢,尽管我没有完全像你那样做,但match and group
帮助了我。我只是没有使用forEach
,而是采取了另一个步骤,将所有createdAt
取出到一个数组中,然后使用$in
获取所有createdAt
,然后更新它们
获取文件的干净方式... +1以上是关于mongoose 使用 $in 并且只用最近的时间戳更新一个的主要内容,如果未能解决你的问题,请参考以下文章
Mongoose/MongoDB:$in 和 .sort()
在 MongoDB 中将 ObjectId 与 Mongoose 一起使用