【问题标题】:Sort Documents Without Existing Field to End of Results将没有现有字段的文档排序到结果末尾
【发布时间】:2016-01-21 10:17:47
【问题描述】:

我有以下文档,少数文档只有bids 字段。

收藏:

   { 
        "_id" : "PqwSsLb2jsqTycMWR", 
        "name" : "aaa", 
        "bids" : [
            {
                "amount" : NumberInt(450)
            }
        ]
    }
    { 
        "_id" : "93EDoQfeYEFk8pyzX", 
        "name" : "bbb"
    }
    { 
        "_id" : "j5wkK5Eagnwuo8Jym", 
        "name" : "ccc", 
        "bids" : [
            {
                "amount" : NumberInt(520)
            }
        ]
    }
    { 
        "_id" : "eLaTyM5h5kqA97WQQ", 
        "name" : "ddd"
    }

如果我使用bids.amount : 1 排序,结果会低于结果

结果:

   { 
       "_id" : "93EDoQfeYEFk8pyzX", 
       "name" : "bbb"
   }
   { 
       "_id" : "eLaTyM5h5kqA97WQQ", 
       "name" : "ddd"
   }
   { 
        "_id" : "PqwSsLb2jsqTycMWR", 
        "name" : "aaa", 
        "bids" : [
            {
                "amount" : NumberInt(450)
            }
        ]
    }
    { 
        "_id" : "j5wkK5Eagnwuo8Jym", 
        "name" : "ccc", 
        "bids" : [
            {
                "amount" : NumberInt(520)
            }
        ]
    }

但我想重新安排bid.amount 应该排在最前面的顺序。

预期结果:

   { 
        "_id" : "PqwSsLb2jsqTycMWR", 
        "name" : "aaa", 
        "bids" : [
            {
                "amount" : NumberInt(450)
            }
        ]
    }
    { 
        "_id" : "j5wkK5Eagnwuo8Jym", 
        "name" : "ccc", 
        "bids" : [
            {
                "amount" : NumberInt(520)
            }
        ]
    }
    { 
        "_id" : "93EDoQfeYEFk8pyzX", 
        "name" : "bbb"
    }
    { 
        "_id" : "eLaTyM5h5kqA97WQQ", 
        "name" : "ddd"
    }

得到预期结果的查询是什么?

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    由于您指定的字段在您的 .sort() 中的所有文档中都不存在,因此如果它不存在,则认为该值是 null,这当然是较低的顺序,因此在排序中具有较高的优先级结果比任何其他值。

    可以改变该响应的唯一方法是从本质上“预测”一个比其他预期值范围更高的排序值,以便这些结果落在其他结果的末尾。这种具有预测值的“加权”查询需要.aggregate() 方法:

    db.collection.aggregate([
        { "$project": {
            "name": 1,
            "bids": 1,
            "sortfield": { "$ifNull": [ "$bids", 999999 ] }
        }},
        { "$sort": { "sortfield": 1 } }
    ])
    

    这使用$project$sort 聚合管道阶段以所需顺序获得结果。首先使用$ifNull 操作根据存在的数据决定在投影文档的“sortfield”属性中放置什么,然后在$sort 聚合管道阶段使用该值。

    您还可以在管道开始时将普通查询操作与$match 管道阶段集成,建议减少需要在$project 阶段处理的文档。

    对于不包含必填字段的文档,“sortfield”的值将高于预期值,并且这些文档将出现在末尾而不是开头。

    【讨论】:

    • 排序完成后别忘了恢复修改过的文件
    猜你喜欢
    • 2018-07-05
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多