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

MongoDB - custom sort aggregation with embedded doccument

application 集合包括 status 字段和一个嵌入的 offer 字段,后者还有一个 status 字段。 application 可能没有 offer.

排序要考虑的条件有点复杂

顺序必须是:

第 1 名:有 Offer 的申请,Offer 状态为 pending

第 2 名:没有 Offer 和任何状态值的申请,但以下情况除外:rejectedassignedaccepted

第 3 名:有 Offer 的申请,Offer 状态为:rejected

第 4 名:有 Offer 的申请,Offer 状态为: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- 如果申请没有offer,第一个条件将被忽略

2- 如何在 if 条件

中使用 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"
}

您可以在 if 条件中使用 $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
        } }
    } }