gpt4 book ai didi

node.js - 根据子文档日期查找即将发布的文档

转载 作者:可可西里 更新时间:2023-11-01 09:28:39 25 4
gpt4 key购买 nike

假设我有一些 MongoDB 事件文档,每个文档都有许多在不同日期发生的 session 。我们可以将其表示为:

db.events.insert([
{
_id: '5be9860fcb16d525543cafe1',
name: 'Past',
host: '5be9860fcb16d525543daff1',
sessions: [
{ date: new Date(Date.now() - 1e8 ) },
{ date: new Date(Date.now() + 1e8 ) }
]
}, {
_id: '5be9860fcb16d525543cafe2',
name: 'Future',
host: '5be9860fcb16d525543daff2',
sessions: [
{ date: new Date(Date.now() + 2e8) },
{ date: new Date(Date.now() + 3e8) }
]
}
]);

我想找到所有还没有举行第一次 session 的事件。所以我想找到“ future ”而不是“过去”。

目前我正在使用 Mongoose 和 Express 来做:

  Event.aggregate([
{ $unwind: '$sessions' }, {
$group: {
_id: '$_id',
startDate: { $min: '$sessions.date' }
}
},
{ $sort:{ startDate: 1 } }, {
$match: { startDate: { $gte: new Date() } }
}
])
.then(result => Event.find({ _id: result.map(result => result._id) }))
.then(event => Event.populate(events, 'host'))
.then(events => res.json(events))

但我觉得我正在制造恶劣天气。两次点击数据库(如果包含 populate 语句,则点击三次)和一个大而复杂的 aggregate 语句。

有没有更简单的方法来做到这一点?理想情况下,只涉及一次数据库访问。

最佳答案

你可以使用 $reduce 折叠数组并查找是否有任何元素有过去的 session 。

为了说明这一点,请考虑运行以下聚合管道:

db.events.aggregate([
{ "$match": { "sessions.date": { "$gte": new Date() } } },
{ "$addFields": {
"hasPastSession": {
"$reduce": {
"input": "$sessions.date",
"initialValue": false,
"in": {
"$or" : [
"$$value",
{ "$lt": ["$$this", new Date()] }
]
}
}
}
} },
//{ "$match": { "hasPastSession": false } }
])

基于上面的示例,这将产生以下带有额外字段的文档

/* 1 */
{
"_id" : "5be9860fcb16d525543cafe1",
"name" : "Past",
"host" : "5be9860fcb16d525543daff1",
"sessions" : [
{
"date" : ISODate("2019-01-03T12:04:36.174Z")
},
{
"date" : ISODate("2019-01-05T19:37:56.174Z")
}
],
"hasPastSession" : true
}

/* 2 */
{
"_id" : "5be9860fcb16d525543cafe2",
"name" : "Future",
"host" : "5be9860fcb16d525543daff2",
"sessions" : [
{
"date" : ISODate("2019-01-06T23:24:36.174Z")
},
{
"date" : ISODate("2019-01-08T03:11:16.174Z")
}
],
"hasPastSession" : false
}

有了这个聚合管道,您就可以利用 $expr 并在 find() 中使用管道表达式作为查询 方法(或使用上面的聚合操作但最后启用了 $match 管道步骤)作为

db.events.find(
{ "$expr": {
"$eq": [
false,
{ "$reduce": {
"input": "$sessions.date",
"initialValue": false,
"in": {
"$or" : [
"$$value",
{ "$lt": ["$$this", new Date()] }
]
}
} }
]
} }
)

返回文档

{
"_id" : "5be9860fcb16d525543cafe2",
"name" : "Future",
"host" : "5be9860fcb16d525543daff2",
"sessions" : [
{
"date" : ISODate("2019-01-06T23:24:36.174Z")
},
{
"date" : ISODate("2019-01-08T03:11:16.174Z")
}
]
}

关于node.js - 根据子文档日期查找即将发布的文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54041820/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com