英文:
How to sort mongodb collection using a static value and other field value desending
问题
我的收藏是一个具有以下结构的产品列表
{
_id
name
status // 枚举 ['active','sold','reserved','pending']
.
.
createdAt
}
我需要的是一个排序功能,同时传递状态值给系统,我将在下面给出一个示例
> 情况:如果状态 = 'active' ,则结果应按如下方式排序
> 所有状态为active的产品应首先显示(Active列表本身应按createdAt降序排列)
> 剩余产品应按createdAt降序排列
对所有其他状态值都要按照相同的方式操作。
如果状态为空,则按降序列出所有内容
我尝试过以下方法
db.products.aggregate([
{
$project: {
"_id":1,
"name":1,
"status":1,
"createdAt":1
}
},
{$sort:{status:"active", createdAt:-1}}, // 错误
{$sort:{status:1, createdAt:-1}}, // 结果有效但不如预期
])
任何帮助将不胜感激。
英文:
My colection is a list of products with the following structure
{
_id
name
status // enum ['active','sold','reserved','pending']
.
.
createdAt
}
What I need is a sort feature along with the status value passed to the system, I ll give an example below
> case: If status = 'active' , Then result should sort as given below
> All products with status active should come first (Active list itself should be in createdAt desc order)
> Remaining products should list createdAt in desc order
Follow the same with all other status value.
If status is empty then list everything in desc order
What I tried is given below
db.products.aggregate([
{
$project: {
"_id":1,
"name":1,
"status":1,
"createdAt":1
}
},
{$sort:{status:"active", createdAt:-1}}, // Error
{$sort:{status:1, createdAt:-1}}, // Result work but not as expected
])
Any help would be much appreciated
答案1
得分: 2
我成功地得到了一个解决方案,如下所示,但如果存在更好的解决方案,我愿意接受。
db.products.aggregate([
{
$project: {
"_id": 1,
"name": 1,
"status": 1,
"createdAt": 1,
"timeStamp": {
"$switch": {
"branches": [
{ "case": { "$eq": ["$status", "pending"] }, "then": 99999999999999 },
],
"default": { "$toLong": "$createdAt" }
}
},
"createdTime": {
"$toLong": "$createdAt"
}
}
},
{ $sort: { timeStamp: -1, createdTime: -1 } }
])
英文:
I managed to get one solution which is listed below, But I am open to any better solution if exists
db.products.aggregate([
{
$project: {
"_id":1,
"name":1,
"status":1,
"createdAt":1,
"timeStamp": {
"$switch": {
"branches": [
{ "case": { "$eq": [ "$status", "pending" ] }, "then": 99999999999999 },
],
"default": {"$toLong": "$createdAt"}
}
},
"createdTime": {
"$toLong": "$createdAt"
}
}
},
{$sort:{timeStamp:-1, createdTime:-1}}
])
答案2
得分: 1
Another option is to create a separate field which specifies which status value to come first
- Add a field
sortBy
which assigns 0 if it has the status value that should come first, otherwise assign 1. - Do the usual sorting with
sortBy
ascending andcreatedAt
descending. - Remove the newly added field from the output result using
project
.
const status = 'active';
db.products.aggregate([
{ $addFields: { sortBy: { $cond: [ { $eq: [ "$status", status ] }, 0, 1 ] } } },
{ $sort: { sortBy: 1, createdAt: -1 } },
{ $project: { sortBy: 0 } }
])
英文:
Another option is to create a separate field which specifies which status value to come first
- Add a field
sortBy
which assigns 0 if it is has the status value that should come first else assign 1 - Do the usual sorting
sortBy
ascending andcreatedAt
descending - Remove the newly added field from the output result using
project
const status = 'active'
db.products.aggregate([
{ $addFields: { sortBy: { $cond: [ { $eq: [ "$status", status ] }, 0, 1 ] } } },
{ $sort: { sortBy: 1, createdAt: -1 } },
{ $project: { sortBy: 0 } }
])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论