mongodb内部查询聚合

费萨尔·艾哈迈德(Faysal Ahmed)

这是我收藏的简单形式。

{ 
  "_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在列表中再次显示,并且他匹配的“否”是错误的。从技术上讲,它是3,但返回1,因为我的查询使它的计算结果类似于1。

如何更新聚合查询,以解决问题。我知道有一种方法可以排除$nin在查找中放入用户字段的用户,但是我不会事先拥有用户列表,并且在实际情况下该列表可能有数百个。有什么办法可以在运行时中找到job_112 and/or job_113之前匹配的列表

欢迎对如何改进此方法或任何其他新方法的任何建议

米克尔

您可以在一个查询中执行此操作。您可以从开始$match但包括所有工作开始。然后,您可以使用$groupwith$push收集每个用户的所有作业。在最后阶段,有两种可能性:matched字段可以是1代表收集到的作业$ filter -ed数组job_111$ size不会少于,因为这两种情况之一必须匹配,因此您可以使用$ max来获取112

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"] ] } 
                            }   
                        } 
                    }
                ]
            }
        }
    }
])

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章