【问题标题】:Project different fields based on different condition根据不同的条件投影不同的字段
【发布时间】:2017-01-15 20:31:06
【问题描述】:

我在 MongoDB 中使用聚合,现在我遇到了一个问题,我想根据条件匹配与否来投影我的字段。

例如我有一个字段coupon_type,我将检查它的值是否等于1,然后我将投影字段["curr_ctr", "total_coupons"],否则如果它的值不等于1,那么我将投影字段["curr_ctr", "total_coupons", "curr_ctr", "coupons"].

我可以使用两个查询并并行运行它们,但我正在尝试使用一个查询来实现我的结果。

谁能告诉我如何在一个查询中做到这一点?

更新

我的文件如下所示

[{ "_id" : ObjectId("5878e1edf1df5a2b69bcf60e"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 1 } ,
{ "_id" : ObjectId("5878e1eff1df5a2b69bcf60f"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 0 } ,
{ "_id" : ObjectId("5878e1f1f1df5a2b69bcf610"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 1 } ,
{ "_id" : ObjectId("5878e1f3f1df5a2b69bcf611"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 1 } ,
{ "_id" : ObjectId("5878e1f5f1df5a2b69bcf612"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 11 } ,
{ "_id" : ObjectId("5878e1f7f1df5a2b69bcf613"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 110 },
{ "_id" : ObjectId("5878e1f9f1df5a2b69bcf614"), "curr_ctr": 12, "total_coupons":35, "coupons": ["hello", "hello2"], "coupon_type" : 0 } ]

现在对于所有的 coupon_type 等于 0 我要投射字段 ["curr_ctr", "total_coupons", "curr_ctr", "coupons"] 并且对于所有 coupon_type 不等于 0 我要投射字段 ["curr_ctr", "total_coupons"]

更新

其实我想将coupons数组从索引n投影到n+1,其中n是用户的输入。

【问题讨论】:

  • 是的,您可以使用 $cond 执行此操作
  • 我知道 $cond 但是如何使用 $cond 来投影不同的字段?你能告诉我这样做的代码吗??
  • 发布示例文档和预期输出以及您尝试了什么的更好方法?
  • 正如我已经提到的,我的字段都与上面相同,关于我尝试过的内容,我看到了这个 $cond 但不知道如何在我的场景中使用它。

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

假设您的收藏包含以下文档

[{ "_id" : ObjectId("5878e1edf1df5a2b69bcf60e"), "coupon_type" : 1 } ,
{ "_id" : ObjectId("5878e1eff1df5a2b69bcf60f"), "coupon_type" : 0 } ,
{ "_id" : ObjectId("5878e1f1f1df5a2b69bcf610"), "coupon_type" : 1 } ,
{ "_id" : ObjectId("5878e1f3f1df5a2b69bcf611"), "coupon_type" : 1 } ,
{ "_id" : ObjectId("5878e1f5f1df5a2b69bcf612"), "coupon_type" : 11 } ,
{ "_id" : ObjectId("5878e1f7f1df5a2b69bcf613"), "coupon_type" : 110 },
{ "_id" : ObjectId("5878e1f9f1df5a2b69bcf614"), "coupon_type" : 0 } ]

现在你需要在project 中使用$eq 作为:

db.collectoin.aggregate({
  "$project": {
    "result": {
      "$cond": {
    "if": {
      "$eq": ["$coupon_type", 1]
    },
    "then": ["curr_ctr", "total_coupons"],
    "else": ["curr_ctr", "total_coupons", "curr_ctr", "coupons"]
      }
    }
  }
})

根据新的更新,您应该像这样修改查询:

db.collection.aggregate({
  "$project": {
    "result": {
      "$cond": {
    "if": {
      "$eq": ["$coupon_type", 1]
    },
    "then": ["$curr_ctr", "$total_coupons", "$coupons"],
    "else": ["$curr_ctr", "$total_coupons"]
      }
    }
  }
})

更新

根据新的更新,让我们考虑一下用户为 ex 提供的 n。 :var n = 1;

现在查询如下:

db.coupon.aggregate({
  "$project": {
    "result": {
      "$cond": {
    "if": {
      "$eq": ["$coupon_type", 1]
    },
    "then": ["$curr_ctr", "$total_coupons", {
      "coupons": {
        "$slice": ["$coupons", n, n + 1]
      }
    }],
    "else": ["$curr_ctr", "$total_coupons"]
      }
    }
  }
})

【讨论】:

  • 不确定两件事 1) 您的代码是返回字段值数组还是字符串数组。 2)OP是否想要获取值数组。然后检查数组的长度并通过索引获取值。我打赌他想将文档字段作为字段
  • @SergeyBerezovskiy 我也很确定 OP 需要值数组,我已经在评论中要求显示示例文档和预期输出,但 OP 没有正确解释。所以我认为 OP 只需要如何编写总体条件,这就是为什么我以非常简单的方式发布它的原因。让我们看看 OP 将如何更新问题,然后我将根据它们修改答案。
  • 对不起,但它不起作用,因为我想投影我的数组中存在的字段。请参阅我编辑的问题。还是谢谢你。
  • @PrakashKumar 如果您需要密钥名称,请检查新的更新答案,然后使用$literal
  • 你能看到我更新的帖子吗,实际上我想将数组从索引 n 投影到 n+1,你能告诉我根据你的代码我怎么可能做到这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-31
相关资源
最近更新 更多