如何使用静态值和其他字段值降序对MongoDB集合进行排序。

huangapple go评论59阅读模式
英文:

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

  1. Add a field sortBy which assigns 0 if it has the status value that should come first, otherwise assign 1.
  2. Do the usual sorting with sortBy ascending and createdAt descending.
  3. 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 } }
])

playground

英文:

Another option is to create a separate field which specifies which status value to come first

  1. Add a field sortBy which assigns 0 if it is has the status value that should come first else assign 1
  2. Do the usual sorting sortBy ascending and createdAt descending
  3. 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 } }
])

playground

huangapple
  • 本文由 发表于 2023年5月25日 13:37:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76329210.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定