MongoDB - 嵌入文档的自定义排序聚合
MongoDB - custom sort aggregation with embedded doccument
application
集合包括 status
字段和一个嵌入的 offer
字段,后者还有一个 status
字段。 application
可能没有 offer
.
排序要考虑的条件有点复杂
顺序必须是:
第 1 名:有 Offer 的申请,Offer 状态为 pending
第 2 名:没有 Offer 和任何状态值的申请,但以下情况除外:rejected
、assigned
、accepted
第 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 条件
中使用 and
或 or
一些示例申请文件:
{
"_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
} }
} }
application
集合包括 status
字段和一个嵌入的 offer
字段,后者还有一个 status
字段。 application
可能没有 offer
.
排序要考虑的条件有点复杂
顺序必须是:
第 1 名:有 Offer 的申请,Offer 状态为 pending
第 2 名:没有 Offer 和任何状态值的申请,但以下情况除外:rejected
、assigned
、accepted
第 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 条件
中使用and
或 or
一些示例申请文件:
{
"_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
} }
} }