簡體   English   中英

mongodb內部查詢聚合

[英]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獲得12

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM