首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >组,排序并首先选择

组,排序并首先选择
EN

Stack Overflow用户
提问于 2015-10-29 19:36:43
回答 1查看 1.4K关注 0票数 1

比方说,我有这样的收藏:

代码语言:javascript
运行
复制
{
  couponId: "abc",
  state: "valid",
  date: "2015-11-01"
}
{
  couponId: "abc",
  state: "expired",
  date: "2015-10-01"
}
{
  couponId: "abc",
  state: "invalid",
  date: "2015-09-01"
}
{
  couponId: "xyz",
  state: "invalid",
  date: "2015-11-01"
}
{
  couponId: "xyz",
  state: "expired",
  date: "2015-10-01"
}
{
  couponId: "xyz",
  state: "expired",
  date: "2015-09-01"
}
...

优惠券可以有效/无效/过期。现在,我想获取一个优惠券列表,其中每个优惠券都是根据这个逻辑选择的:

  • 如果存在“有效”优惠券,请使用
  • 否则,如果存在“过期”优惠券,请使用
  • 否则得到“无效”优惠券。

将这一逻辑应用于上述列表应该会产生以下结果:

代码语言:javascript
运行
复制
    {
      couponId: "abc", /* for "abc" "valid" exists */
      state: "valid",
      date: "2015-11-01"
    },
    {
      couponId: "xyz", /* for "xyz" "valid" does not exist, use the next best "expired" */
      state: "expired",
      date: "2015-11-01"
    }

基本上,有效>过期>无效

我曾经想过使用聚合操作,试图模仿SQL groupby+sort+selectFirst,

代码语言:javascript
运行
复制
db.xyz.aggregate([
  {$sort : { couponId: 1, state: -1 } },
  {$group : { _id : "$couponId", document: {$first : "$$ROOT"} }}
])

显然,这是不起作用的,因为"state“字段应该有一个自定义排序( valid>expired>invalid )。因此,可以在聚合中实现自定义排序吗?

还是有更好的方法来做我在这里想做的事?

EN

回答 1

Stack Overflow用户

发布于 2015-10-29 20:02:17

一个更好的方法,尽管不是那么干净/漂亮(在我看来有点麻烦:P ),是在$cond管道阶段用上面的条件/逻辑嵌套一些$group操作符表达式。最好的解释是运行以下聚合管道:

代码语言:javascript
运行
复制
db.xyz.aggregate([
    {
        "$group": {
            "_id": "$couponId",
            "state": {
                "$first": {
                    "$cond": [
                        { "$eq": ["$state", "valid"]},
                        "$state",
                        {
                           "$cond": [
                                { "$eq": ["$state", "invalid"]},
                                "$state",
                                "expired"
                            ]
                        }
                    ]
                }
            },
            "date": {
                "$first": {
                    "$cond": [
                        { "$eq": ["$state", "valid"]},
                        "$date",
                        {
                           "$cond": [
                                { "$eq": ["$state", "invalid"]},
                                "$date",
                                {
                                   "$cond": [
                                        { "$eq": ["$state", "expired"]},
                                        "$date", 
                                        "1970-01-01"
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        }
    }
])

样本输出

代码语言:javascript
运行
复制
/* 0 */
{
    "result" : [ 
        {
            "_id" : "xyz",
            "state" : "invalid",
            "date" : "2015-11-01"
        }, 
        {
            "_id" : "abc",
            "state" : "valid",
            "date" : "2015-11-01"
        }
    ],
    "ok" : 1
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33423161

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档