MongoDB - 具有嵌入式文档的自定义排序聚合

时间:2017-11-14 15:21:38

标签: mongodb mongodb-query aggregation

application集合包含status字段和嵌入式offer字段,其中还包含status字段。 application可能没有offer

我必须考虑排序的条件有点复杂。

订单必须是:

1st:具有优惠和优惠状态的申请状态为pending

第二名:没有优惠的申请和状态值除外:rejectedassignedaccepted

第3期:优惠申请和优惠状态为:rejected

第4期:优惠申请和优惠状态为:withdrawn

第五:其他案例

我正在尝试的查询是:

db.application.aggregate([
{
    "$project": {
        "_id": 1,
        "status": 1,
        "job": 1,
        "offer": 1,
        "user": 1,
        "denormalized": 1,
        "custom_sort": {
            $cond: {
                if: { $eq: ["offer.$status", "pending"] }, then: 1,
                else: {
                    $cond: {
                        if: { $ne: ["$status", ["rejected", "assigned", "accepted"]] }, then: 2,
                        else: {
                            $cond: {
                                if: { $eq: ["offer$status", "rejected"] }, then: 3,
                                else: {
                                    $cond: {
                                        if: { $eq: ["offer$status", "withdrawn"] }, then: 4,
                                        else: 5
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
{"$sort": {"custom_sort": 1}},
{ "$project": { "_id": 1, "status": 1, "job": 1, "offer": 1, "user": 1, "denormalized": 1, "custom_sort": 1 } }
])

查询有效。但是,并不像预期的那样。 我有两个问题:

1-如果申请没有报价,第一个条件将被忽略

2-如果条件

,我如何使用andor

一些示例申请文件:

{
    "_id" : ObjectId("59f0c8c517587d306033f9f2"),
    "status" : "new",
    "offer" : {
        "status" : "withdrawn"
    }
},

{
    "_id" : ObjectId("59f0b38517587d29bb1eb6b3"),
    "status" : "new",
    "offer" : {
        "status" : "rejected"
    }
},

{
    "_id" : ObjectId("59f0b35717587d29bb1eb6b2"),
    "status" : "new",
    "offer" : {
        "status" : "pending"
    }
},

{
    "_id" : ObjectId("58de110e46fc387b39744285"),
    "status" : "rejected"
},

{
    "_id" : ObjectId("58de119946fc3876035f823c"),
    "status" : "new"
}

1 个答案:

答案 0 :(得分:1)

如果有条件,您可以使用$and and $or operators,但在此特定情况下您不需要它们。

$switch案例会更好:

    "custom_sort": { $cond: {
        if: { $eq: [ { $type: "$offer" }, "object" ] }, 
        then: { $switch: {
            branches: [
                { case: { $eq: [ "$offer.status", "pending" ] }, then: 1 },
                { case: { $eq: [ "$offer.status", "rejected" ] }, then: 3 },
                { case: { $eq: [ "$offer.status", "withdrawn" ] }, then: 4 },
            ],
            default: 5
        } },
        else: { $cond : {
            if: { $in: [ "$status", [ "rejected", "assigned", "accepted" ] ] },
            then: 2,
            else: 5
        } }
    } }