我正在为页面制作过滤系统。我有以下架构结构:
User: {
firstName
lastName
email
subscriptions: [
{
id: '5a687c7680eab407064c3990'
plan: "TRIAL"
startDate: '2018-03-01'
endDate: '2018-04-01'
status: 'EXPIRED'
}
{
id: '5afacc040e53b4075dcdd600'
plan: "BASIC"
startDate: '2018-04-01'
endDate: '2018-05-01'
status: 'EXPIRED'
}
{
id: '5afacc040e53b4075dcdd600'
plan: "BASIC"
startDate: '2018-05-01'
endDate: '2018-06-01'
status: 'CANCELLED'
}
]
}
我需要获得一个包含以下内容的用户列表:
这应该返回null。
这是我试过的:
User.find({
$or:
[
{ firstName: { $regex: args.search, $options: 'i' } },
{ lastName: { $regex: args.search, $options: 'i' } },
{ email: { $regex: args.search, $options: 'i' } },
],
$and:
[
{ 'subscriptions.status': 'EXPIRED' },
{ 'subscriptions.plan': 'TRIAL' },
],
}).limit(limit).skip(skip);
问题是我只需要搜索用户的最新订阅(具有最新startDate的订阅),而不是数组中的每个对象。有没有办法做到这一点?我在架构上也有一个虚拟字段,但似乎你无法查询虚拟字段。
答案 0 :(得分:0)
您应该尝试使用聚合查询来执行此操作...
首先你必须
$match
firstName,lastName,email $unwind
根据startDate
然后再次$match
获取计划和状态
db.collection.aggregate([
{
$match: {
$or: [
{
firstName: {
$regex: args.search,
$options: "i"
}
},
{
lastName: {
$regex: args.search,
$options: "i"
}
},
{
email: {
$regex: args.search,
$options: "i"
}
}
]
}
},
{
$unwind: "$subscriptions"
},
{
$sort: {
"subscriptions.startDate": -1
}
},
{
$group: {
_id: "$_id",
subscriptions: {
"$first": "$subscriptions"
}
}
},
{
$match: {
"subscriptions.status": "EXPIRED",
"subscriptions.plan": "TRIAL"
}
},
])