Mongo: how to sort by external weight

后端 未结 1 2084
误落风尘
误落风尘 2020-12-06 13:33

Following this question which @NeilLunn has gracefully answered, here is my problem in more detail.

This is the set of documents, some have user_id some don\'t. The

相关标签:
1条回答
  • 2020-12-06 14:06

    Given the array [4,7,90,1] what you want in your query is this:

    db.collection.aggregate([
       { "$project": {
           "user_id": 1,
           "content": 1,
           "date": 1,
           "weight": { "$or": [
               { "$eq": ["$user_id": 4] }, 
               { "$eq": ["$user_id": 7] }, 
               { "$eq": ["$user_id": 90] }, 
               { "$eq": ["$user_id": 1] }, 
           ]}
       }},
       { "$sort": { "weight": -1, "date": -1 } }
    ])
    

    So what that does is, for every item contained in that $or condition, the user_id field is tested against the supplied value, and $eq returns 1 or 0 for true or false.

    What you do in your code is for each item you have in the array you build the array condition of $or. So it's just creating a hash structure for each equals condition, passing it to an array and plugging that in as the array value for the $or condition.

    I probably should have left the $cond operator out of the previous code so this part would have been clearer.

    Here's some code for the Ruby Brain:

    userList = [4, 7, 90, 1];
    
    orCond = [];
    
    userList.each do |userId|
      orCond.push({ '$eq' => [ 'user_id', userId ] })
    end
    
    pipeline = [
        { '$project' => {
            'user_id' => 1,
            'content' => 1,
            'date' => 1,
            'weight' => { '$or' => orCond }
        }},
        { '$sort' => { 'weight' => -1, 'date' => -1 } }
    ]
    

    If you want to have individual weights and we'll assume key value pairs, then you need to nest with $cond :

    db.collection.aggregate([
       { "$project": {
           "user_id": 1,
           "content": 1,
           "date": 1,
           "weight": { "$cond": [
               { "$eq": ["$user_id": 4] },
               10,
               { "$cond": [ 
                   { "$eq": ["$user_id": 7] },
                   9,
                   { "$cond": [
                       { "$eq": ["$user_id": 90] },
                       7,
                       { "$cond": [
                           { "$eq": ["$user_id": 1] },
                           8, 
                           0
                       ]}
                   ]}
               ]}
           ]}
       }},
       { "$sort": { "weight": -1, "date": -1 } }
    ])
    

    Note that it's just a return value, these do not need to be in order. And you can think about the generation of that.

    For generating this structure see here:

    https://stackoverflow.com/a/22213246/2313887

    0 讨论(0)
提交回复
热议问题