How to robustly describe conditional expressions with AND, OR in JSON?
Asked Answered
G

1

14

Say I have an expression:

( A >= 10 && B == 20 ) || ( C < 30 ) || ( D != 50 )

I can suggest the following JSON to store/represent this expression:

{ "filter": 
    [
        { "var":"A", "condition":"ge", "num":10 },
        { "var":"B", "condition":"e", "num":20 }
    ],
    [
        { "var":"C", "condition":"lt", "num":30 }
    ],
    [
        { "var":"D", "condition":"ne", "num":50 }
    ]
}

in which "filter" maps to an array of sub-arrays. All elements in each sub-array are associated with AND, while all sub-arrays are associated with OR.

Is there anything I've overlooked in writing the JSON like this?

Guzel answered 29/3, 2015 at 13:43 Comment(2)
Seems pretty good for a representation in json.Southward
What if you have A < B ? or even 10 < A? What is the order?Korten
E
16

You're making a couple of assumptions here:

  1. Comparisons will be always be between a variable and a number, and never between two variables or two numbers.
  2. The variable will always be on the left hand side of the comparison, and the number on the right.

Those assumptions may be correct for your particular use case, but a more future-proof approach would be to treat comparisons similarly to functions with arguments:

{ "ge": ["A", 10] }

Also, while your idea of using an array of objects to represent AND and an array of arrays to represent OR is clever, it might not be immediately obvious to a human being tasked with writing code to parse it. Reusing the idea of an object where the key represents a function and its associated value the arguments is more expressive:

{ "all": [<condition 1>, <condition 2>, ...] }

Putting those two ideas together, we get something like this:

{ "any": [
    { "all": [
        { "ge": ["A", 10] },
        { "eq": ["B", 20] }
    ]},
    { "lt": ["C", 30] },
    { "ne": ["D", 50] }
]}
Emylee answered 29/3, 2015 at 14:29 Comment(6)
I like the use of any and or to represent the operators or and and. none could be introduced as well, if needed. none would do the job of not if it had one child, or of nor with multiple children.Spracklen
Thanks, Zero! It is clean and efficient. Using the key "any" and "all", writing code to recursively parse the JSON is easy.Guzel
@Guzel that's another useful feature of writing it this way, yes :-) Glad to hear my answer helped you ...Emylee
This is essentially the format used by the javascript package json-logic. There are also php and python parsers available for this format.Verdugo
Well well, so it is ... thanks @Verdugo :-) I think a little care is warranted, though, since it appears the Python and JS versions interpret == and === differently (according to each language's notion of equality and identity). I can see that wrinkle causing hard-to-spot bugs, and it worries me a little.Emylee
mongodb expression syntax docs.mongodb.com/manual/reference/operator/queryMerissa

© 2022 - 2024 — McMap. All rights reserved.