MongoDB:如何将变量用作运算符

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

mongodb: how to use variable as operator

问题

我正在尝试实现以下内容:

这是按预期工作的,但我需要做的是,而不是使用$lt操作符,使用items.condition中的操作符,类似于这样:

这正是我尝试过的,但不起作用。有没有办法实现这个?

使用变量作为值很容易,但我不知道如何将其用作操作符。

英文:

What I'm trying to achieve is the following:

let validations = [
    {
        "label": "kpis.avgLatency",
        "program":"ping-test",
        "multiple":false,
        "conditions" :[
            {
                "operator" : "$gt",
                "value": NumberInt(-107)
            },
            {
                "operator" : "$lt",
                "value": NumberInt(0)
            }
        ]
    }
]
validations.map((item) => {
    let test = db.task.aggregate([
      {$addFields: {validation: item}},
      {$match: { program: item.program}},
      {$project:{
        validation2: {
          $map: {
            input: item.conditions,
            as: "val",
            in: { $cond:{ if: { $lt: ['$validation.label', '$$val.value'] } , then: true, else: false} }
        }}
    }}
    ,
    ]).toArray();

    print(test);
})

This is working as expected, but what I need to do is, instead of the $lt operator, use the operator of my items.condition, something like this:

in: { $cond:{ if: { '$$val.operator': ['$validation.label', '$$val.value'] } , then: true, else: false} }

That's exactly what I've tried, but is not working. Is there any way to achieve that?

It's easy to use vars as values, but I don't know how to use it as an operator.

答案1

得分: 1

我不熟悉这种选项,但您可以通过使用分支来绕过它(因为相关运算符的数量有限)。这不是最优雅的方法。

db.collection.aggregate([
  {$addFields: {validation: {label: 7}}},
  {$project: {
      validation2: {
        $map: {
          input: "$conditions",
          as: "val",
          in: {$switch: {
              branches: [
                {
                  case: {$eq: ["$val.operator", "$gt"]},
                  then: {$cond: {
                      if: {$gt: ["$validation.label", "$$val.value"]},
                      then: true,
                      else: false
                  }}
                },
                {
                  case: {$eq: ["$val.operator", "$lt"]},
                  then: {$cond: {
                      if: {$lt: ["$validation.label", "$$val.value"]},
                      then: true,
                      else: false
                  }}
                },
                //...
              ]
          }}
        }
      }
  }}
])

playground示例上查看其工作原理。

英文:

I'm not familiar with such an option, but you can bypass it by using branches (as the number of relevant operators is limited). Not the most elegant way of doing things though.

db.collection.aggregate([
  {$addFields: {validation: {label: 7}}},
  {$project: {
      validation2: {
        $map: {
          input: "$conditions",
          as: "val",
          in: {$switch: {
              branches: [
                {
                  case: {$eq: ["$val.operator", "$gt"]},
                  then: {$cond: {
                      if: {$gt: ["$validation.label", "$$val.value"]},
                      then: true,
                      else: false
                  }}
                },
                {
                  case: {$eq: ["$val.operator", "$lt"]},
                  then: {$cond: {
                      if: {$lt: ["$validation.label", "$$val.value"]},
                      then: true,
                      else: false
                  }}
                },
                //...
              ]
          }}
        }
      }
  }}
])

See how it works on the playground example

huangapple
  • 本文由 发表于 2023年7月13日 00:11:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76672563.html
匿名

发表评论

匿名网友

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

确定