[英]mongodb inner query in aggregation
这是我收藏的简单形式。
{
"_id" : "abcdfg",
"job_id" : "job_111",
"user_id" : "user_001",
"job_createdAt" : ISODate("2018-03-02T15:02:24.122+0000"),
"score" : 240.91185185185185
}
假设某个用户发布了3个职位。 job_111, job_112, job_113
。 现在, user1,user2,user3,user4
已与job_112 and 113
匹配(表示集合中有一个文档)。 并且user5
与所有3个作业匹配。 user6
专门匹配上job_111
现在,在聚合查询中,我想显示用户列表以及已匹配的作业数。 但是有一个条件。 与job_112 and job_113
匹配的用户具有更高的优先级(因为它们是最近创建的),并且将首先显示。 现在我已经这样查询了
[
{ $match: { job_id: { $in: ['job_112', 'job_113'] } } },
{
$group:
{ _id: '$user_id', matched: { $sum: 1 }, score: { $max: '$score' } }
},
{ $sort: { score: -1 } },
{ $skip: skip },
{ $limit: limit }
]
这会给我像这样的东西
[
{
user_id: 'user1',
matched: 2
},
{
user_id: 'user2',
matched: 2
},
{
user_id: 'user4',
matched: 2
},
{
user_id: 'user5',
matched: 2
}
]
现在,当该列表结束时(我使用分页和聚合计数来找出它),我想显示仅与job_111
匹配的用户。 现在我的查询变成这样
[
{ $match: { job_id: { $in: ['job_111'] } } },
{
$group:
{ _id: '$user_id', matched: { $sum: 1 }, score: { $max: '$score' } }
},
{ $sort: { score: -1 } },
{ $skip: 0 },// << skip value resets to 0 since $in value changes
{ $limit: limit }
]
这样返回的结果是这样的
[
{
user_id: 'user5',
matched: 1
},
{
user_id: 'user6',
matched: 1
},
]
现在这个结果有2个问题,我不想在列表中再次显示user5
,而他匹配的no是错误的。 从技术上讲,它是3,但是返回1,因为我的查询使它的计算结果类似于1。
如何更新聚合查询,以解决该问题。 我知道可以排除将$nin
放在用户字段中的用户,但是我不会事先拥有用户列表,在实际情况下该列表可能有数百个。 有什么方法可以在运行时中找到之前在job_112 and/or job_113
中匹配的列表?
欢迎提出有关如何改进此方法或任何其他新方法的建议
您可以在一个查询中执行此操作。 您可以从$match
开始,但包括所有工作。 然后,您可以将$group
与$push
一起使用,以收集每个用户的所有作业。 在最后阶段,有两种可能性: matched
字段可以是1
,代表job_111
也可以是$ filter -ed收集的作业数组的$ size 。 不会少于1
因为这两种情况之一必须匹配,因此您可以使用$ max获得1
或2
db.col.aggregate([
{
$match: { job_id: { $in: ["job_111", "job_112", "job_113"] } }
},
{
$group: {
_id: "$user_id",
jobs: { $push: "$job_id" }
}
},
{
$project: {
matched: {
$max: [ 1,
{
$size: {
$filter: {
input: "$jobs",
as: "job",
cond: { $in: [ "$$job", ["job_112", "job_113"] ] }
}
}
}
]
}
}
}
])
供参考,我发布了最终对我有用的解决方案
[
{ $match: find },
{
$group: {
_id: '$user_id',
jobs: { $push: '$job_id' },
matched: { $sum: 1 },
score: { $max: '$score' }
}
},
{
$project: {
_id: '$_id',
matched: '$matched',
score: '$score',
jobs: '$jobs',
rangeType: {
$cond: {
if: {
$gt: [
{
$size: {
$setIntersection: ['$jobs',['job_112', 'job_113'] ]
}
},
0
]
},
then: 10,
else: 0
}
}
}
},
{ $sort: { rangeType: -1, score: -1 } },
{ $skip: skip },
{ $limit: limit }
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.