我想计算当前活动的resetPassword(用户架构中的子文档)代码数。要激活代码,其到期日期必须大于当前日期。
这是我的用户模式。如果有人请求重置密码,我们将把一个新的{code:X,expiresAt,createdAt}
对象推送到数组中。
id: { type: String, unique: true },
resetPassword: [
{
code: String,
expiresAt: Date,
createdAt: Date,
},
],
我在尝试对活动重置代码的总数求和时遇到问题。下面是我正在运行的查询,它返回一个空数组。。。请注意,如果要删除resetPassword。expiresAt:{$gt:nowdateinmillizes()}
match节,它将返回所有代码。我试着将这个匹配语句移出初始$match
阶段,然后进行放松
[
{
$match: {
"id": userId,
'resetPassword.expiresAt': {
$gt: nowDateInMillisec(),
},
},
},
{
$group: {
_id: '$id',
totalValidResetCodes: {
$sum: {
$size: '$resetPassword',
},
},
},
},
]
这将返回一个空数组,即使我已将到期日期设置为将来的日期。
我还尝试了以下同样的结果(注意我如何在管道中添加$unwind和另一个$match)
[
{
$match: {
"id": userId,
},
},
{
$unwind: '$resetPassword',
},
{
$match: {
'resetPassword.expiresAt': {
$gt: nowDateInMillisec(),
},
}
},
{
$group: {
_id: '$id',
totalValidResetCodes: {
$sum: {
$size: '$resetPassword',
},
},
},
},
]
nowDateInMillisec()
-这只是以毫秒为单位返回当前日期
我做错了什么?
@乔在评论中回答了我的问题。他暗示在匹配过滤器中使用从纪元时间算起的毫秒是行不通的,因为我在Mongoose模式中使用了Date
类型。
因此,我没有这样做:$gt:nowDateInMillisec(),
我只是使用了一个Date
类型,比如:$gt:newdate(),
下面是我的研究,当以mongoDB格式存储的日期格式也应该工作毫秒。下面的测试时间长达一分钟。
> db.users13.find().pretty();
{
"_id" : ObjectId("5f4e03768379a4e3f957641d"),
"id" : "johnc",
"resetPassword" : [
{
"code" : "abc",
"expiresAt" : ISODate("2020-09-02T09:11:18.394Z"),
"createdAt" : ISODate("2020-09-01T08:11:18.394Z")
},
{
"code" : "mno",
"expiresAt" : ISODate("2020-08-25T09:26:18.394Z"),
"createdAt" : ISODate("2020-08-25T08:11:18.394Z")
}
]
}
{
"_id" : ObjectId("5f4e06938379a4e3f957641f"),
"id" : "katey",
"resetPassword" : [
{
"code" : "j2c",
"expiresAt" : ISODate("2020-09-02T08:48:18.394Z"),
"createdAt" : ISODate("2020-09-01T08:11:18.394Z")
},
{
"code" : "rml",
"expiresAt" : ISODate("2020-09-01T08:26:18.394Z"),
"createdAt" : ISODate("2020-09-01T08:11:18.394Z")
}
]
}
> db.users13.aggregate([
{$unwind:"$resetPassword"},
{$match:{"resetPassword.expiresAt":{$gt:ISODate()}}}
]).pretty();
{
"_id" : ObjectId("5f4e03768379a4e3f957641d"),
"id" : "johnc",
"resetPassword" : {
"code" : "abc",
"expiresAt" : ISODate("2020-09-02T09:11:18.394Z"),
"createdAt" : ISODate("2020-09-01T08:11:18.394Z")
}
}
{
"_id" : ObjectId("5f4e06938379a4e3f957641f"),
"id" : "katey",
"resetPassword" : {
"code" : "j2c",
"expiresAt" : ISODate("2020-09-02T08:48:18.394Z"),
"createdAt" : ISODate("2020-09-01T08:11:18.394Z")
}
}
> ISODate()
ISODate("2020-09-01T08:31:37.059Z")
>
你可以在$project
中尝试$减少
,而不是你的所有进程,你需要从这个now返回ISOdate DateInMillisec()
,
db.collection.aggregate([
{ $match: { id: 1 } },
{
$project: {
totalValidResetCodes: {
$reduce: {
input: "$resetPassword",
initialValue: 0,
in: {
$add: [
"$$value",
{
$cond: [
{ $gt: ["$$this.expiresAt", nowDateInMillisec()] },
// If you really want to pass timestamp then try below line
// { $gt: ["$$this.expiresAt", { $toDate: nowDateInMillisec() }] },
1,
0
]
}
]
}
}
}
}
}
])
游乐场
问题内容: 我正在尝试过滤存储桶中的嵌套聚合。 对应: 索引数据: 我正在使用此查询和聚合定义 我从聚合结果中得到的是: 我在筛选存储桶列表时遇到了麻烦,因为它们只能提供所提供的事件ID,因此结果应类似于: 问题答案: 您快到了,只需要在聚合中添加过滤器即可,如下所示: 原因是您的查询将正确选择具有指定事件ID的嵌套事件的所有文档,但是,汇总将对所有选定文档中的所有嵌套事件进行处理。因此,您还需要
问题内容: 我要实现的目标:我不希望查询过滤器过滤“年龄”聚合,并且希望能够对其应用过滤器。 因此,如果我从以下查询开始: 我的聚合“ young_age”将同时被filter_1和filter_2过滤。我不希望我的汇总被filter_1过滤。 在查看文档时,我认为全局聚合可以解决我的问题,因此我编写了以下查询: 但是然后elasticsearch抱怨我的filter_2: “”“在[global
问题内容: 我对Elasticsearch世界真的很陌生。 比方说,我有两个字段嵌套聚集:与: 这段代码可以完美地工作,并且给我这样的东西: 现在,我需要排除所有小于1000的聚合结果,而改为: 是否可以在查询正文中设置此需求?还是我必须在调用者布局中执行过滤器(在我的情况下为javascript)? 提前致谢 问题答案: 下次,M’sieur Toph’:RTFM! 我真的很傻:问了30秒后,我
问题内容: 我认为这很可能非常简单,但是我找不到关于如何在其网站上显示的’filterText’之外添加过滤器的清晰文档。我想做的就是这样简单: 编辑:或者也许我可以以某种方式过滤数据源?我尝试了这个: 但这会引发很多错误。 问题答案: 我发现了一种即时更新的方法。基本上,我保留了所有数据的隐藏集,并且在接收到新数据或更改过滤器后-我将此过滤器应用于完整数据集,并将网格交给过滤后的版本。 这使我可
问题内容: 如何在$ lookup之后添加过滤器,或者有其他方法可以执行此操作? 我的数据收集测试是: 我选择ID 100并汇总孩子: 我回来了: 但我只希望与“值:1”匹配的子项 最后,我希望得到以下结果: 问题答案: 这里的问题实际上是关于一些不同的东西,根本不需要。但是,对于仅从“$lookup之后过滤”标题到达此处的任何人,这些都是适合您的技术: MongoDB 3.6-子管道 较早-$
我有一个返回一组文档(100)的查询。我想对这些应用一个聚合,因为这些是最相关的。当我尝试聚合时,它返回所有结果的聚合,而不是前100个结果的聚合。