1

I would like to compare two input values which are a number but since it is the output of another state machine step from lambda function so it's converted into string values, I want to compare them as a number greater than or equal to and then proceed for other state machine step or terminate it, but it seems not possible to compare them and always going to wrong step.

I have already tried States.FormatNumber and States.StringToJson as suggested in the link: Step functions convert string to number but it didn't work. Is there any way to do it without going to the AWS lambda function to compare it?

e.g: My input is as below:

{
   "v2_table": {
      "count": "2"
   },
   "original_table": {
     "count": "2"
   }
}

AWS Step function is as below:

{
  "StartAt": "CompareCounts",
  "States": {
    "CompareCounts": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.v2_table.count",
          "NumericGreaterThanEqualsPath": "$.original_table.count",
          "Next": "CountsMatch"
        }
      ],
      "Default": "CountsDoNotMatch"
    },
    "CountsMatch": {
      "Type": "Pass",
      "End": true
    },
    "CountsDoNotMatch": {
      "Type": "Pass",
      "End": true
    }
  }
}

For the above input, it goes to CountsDoNotMatch which is incorrect. Execution with the above input results as below

enter image description here

Another example is when I tried to compare the numbers with StringGreaterThanEqualsPath and still failed, Step Function Definition as:

{
  "StartAt": "CompareNumberAsString",
  "States": {
    "CompareNumberAsString": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.argument_one",
          "StringGreaterThanEqualsPath": "$.argument_two",
          "Next": "ArgumentOneGreaterThanEquals"
        }
      ],
      "Default": "ArgumentTwoGreaterThan"
    },
    "ArgumentOneGreaterThanEquals": {
      "Type": "Pass",
      "End": true
    },
    "ArgumentTwoGreaterThan": {
      "Type": "Pass",
      "End": true
    }
  }
}

Executed with the below input:

{
  "argument_one": "11",
  "argument_two": "100"
}

Execution Results which is incorrect as below:

enter image description here

If I changed the comparison with Numeric i.e. NumericGreaterThanEqualsPath in the above step function definition and parameters as numbers then it works as the below, but in my case, input will be number as string data type which is not working.

:enter image description here

2
  • Do note if you are dealing with strings, go left to right. So ”i” > “be” and ‘“9” > “11”’. Need to use convert to numerical to get what you want. Equals will probably work great unless one ends with a decimal. Hope that helps. Good luck. Commented Jun 1, 2024 at 14:07
  • If you really want to compare as strings, check the length. The longer one is greater. If the same, do string compare Commented Jun 1, 2024 at 14:11

2 Answers 2

1

You can use the States.StringToJson intrinsic to first convert your numeric strings to actual numbers (since what is a numeric string really but a json representation of a number) and then do the comparison on the resulting values.

In your question you said it didn't work but didn't elaborate as to why. I am going to guess that you tried to do the conversion within the Choice state. This isn't possible and instead needs an intermediate state.

An example of how to do this follows:

"ConvertNumbers": {
  "Type": "Pass",
  "Parameters": {
    "v2_table_count_numeric.$": "States.StringToJson($.v2_table.count)",
    "original_table_count_numeric.$": "States.StringToJson($.original_table.count)"
  },
  "Next": "CompareCounts"
}

You can use ResultPath to move the injected data into a specific key rather than clobbering the whole input if there is other stuff you need in there or add everything to Parameters but the latter tends to be really clunky.

Then ofc you just do the comparison between $.v2_table_count_numeric and $.original_table_count_numeric.

Intrinsic docs provide a table showing where intrinsics are and are not supported that you may find helpful: https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-intrinsic-functions.html#amazon-states-language-intrinsic-functions-states

Sign up to request clarification or add additional context in comments.

Comments

0

In your Choice state, the StringGreaterThanEqualsPath should be used as the variables are strings.

Full State Machine:

{
  "StartAt": "CompareCounts",
  "States": {
    "CompareCounts": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.v2_table.count",
          "StringGreaterThanEqualsPath": "$.original_table.count",
          "Next": "CountsMatch"
        }
      ],
      "Default": "CountsDoNotMatch"
    },
    "CountsMatch": {
      "Type": "Pass",
      "End": true
    },
    "CountsDoNotMatch": {
      "Type": "Pass",
      "End": true
    }
  }
}

Edit: Photo for input mentioned in comment below.

Test case result.

3 Comments

Thanks for the reply, but I have already tried with StringGreaterThanEqualsPath and it wouldn't work with below parameters: { "v2_table": { "count": "10" }, "original_table": { "count": "1111" } }
Sure it does, it goes through the "CountsDoNotMatch" path because $.v2_table.count < $.original_table.count. I edited my answer with a screenshot of the result.
thanks for checking it out, but I think this string comparison will not if you provide numbers as string, I have created another step function with clear messages and input parameters and updated the questions with examples, please check it then I think you will be able to understand what I mean to say.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.