You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现pin非空按pinOrder否则按created排序?聚合管道支持吗?

问题解答

这个排序需求完全可以通过MongoDB聚合管道实现,不需要额外在业务代码层做排序处理。

核心实现逻辑

核心是通过条件判断动态生成排序键,匹配规则:

  • pin字段非null的文档,按pin_order升序排序,pin_order相同时再按pin字段排序
  • pin字段为null的文档,忽略pin_order字段,直接按created字段升序排序
  • 默认逻辑下pin非空的置顶内容会排在普通内容(pin为null)前面,如果你需要调整两类内容的先后顺序,修改排序分组的权重值即可。

兼容所有MongoDB版本的通用写法

这个写法通过$addFields提前生成临时排序字段,不存在版本兼容问题:

// 替换成你的实际集合名
db.collection.aggregate([
  {
    $addFields: {
      // 排序分组权重:pin非空为0(优先排列),pin为空为1(后排列)
      _sort_group: {
        $cond: { if: { $ne: ["$pin", null] }, then: 0, else: 1 }
      },
      // 动态排序值:pin非空取pin_order,pin为空取created时间
      _sort_val: {
        $cond: { if: { $ne: ["$pin", null] }, then: "$pin_order", else: "$created" }
      }
    }
  },
  {
    $sort: {
      _sort_group: 1,
      _sort_val: 1, // 需要降序排列把1改成-1即可
      pin: 1 // pin非空的内容pin_order相同时,按pin字段升序补排
    }
  },
  {
    // 移除临时生成的排序字段,不返回给前端
    $unset: ["_sort_group", "_sort_val"]
  }
])

MongoDB 4.2+ 精简写法

4.2及以上版本支持在$sort阶段直接使用聚合表达式,不需要提前生成临时字段,写法更简洁:

db.collection.aggregate([
  {
    $sort: {
      // 动态生成第一排序键
      { $cond: { if: { $ne: ["$pin", null] }, then: "$pin_order", else: "$created" } }: 1,
      pin: 1
    }
  }
])

示例数据集执行效果

针对给出的测试数据,执行上述通用管道后返回的排序结果为:

[
  {
    "id": "62b9c1d74321afff4cb4e652",
    "created": "2022-06-27T14:42:31.726Z",
    "pin": "2022-06-27T14:42:31.703Z",
    "pin_order": 1
  },
  {
    "id": "629a212eda64722e286d29f6",
    "created": "2022-06-03T14:56:46.980Z",
    "pin": null,
    "pin_order": 1
  },
  {
    "id": "62b55d6ee0e1fa12861f8cb8",
    "created": "2022-06-24T06:45:02.126Z",
    "pin": null,
    "pin_order": 1
  }
]

注意:如果需求不需要把pin非空的内容整体排在pin为空的内容前面,只需要去掉通用写法里的_sort_group相关逻辑即可。

内容的提问来源于stack exchange,提问作者user10965730

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 03:54:20