Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Group conditions exported incorrectly (except MongoDB) #246

Closed
jetdream opened this issue Jun 23, 2020 · 12 comments · Fixed by #273 or #295
Closed

Group conditions exported incorrectly (except MongoDB) #246

jetdream opened this issue Jun 23, 2020 · 12 comments · Fixed by #273 or #295

Comments

@jetdream
Copy link

Describe the bug
The exported logic of group conditions differs depending on the export format. Looks like only MongoDB export works right.

To Reproduce
go to https://ukrbublik.github.io/react-awesome-query-builder/
and try this:
image

MongoDB export produces code that checks product and score fields simultaneously for each element of results array :

{
  "results": {
    "$elemMatch": {
      "product": "abc",
      "score": {
        "$gt": 8
      }
    }
  }
}

But jsonLogic checks them independently:

{
  "and": [
    {
      "and": [
        {
          "==": [
            {
              "var": "results.product"
            },
            "abc"
          ]
        },
        {
          ">": [
            {
              "var": "results.score"
            },
            8
          ]
        }
      ]
    }
  ]
}

Expected behavior
jsonLogic export should look like that:

{
  "some": [
    {"var":"results"},
    {
      "and": [
        {
          "==": [
            {
              "var": "product"
            },
            "abc"
          ]
        },
        {
          ">": [
            {
              "var": "score"
            },
            8
          ]
        }
      ]
    }
  ]
}
@ukrbublik ukrbublik pinned this issue Aug 2, 2020
@ukrbublik ukrbublik linked a pull request Aug 26, 2020 that will close this issue
@ukrbublik ukrbublik unpinned this issue Aug 26, 2020
@Angelus1383
Copy link

At the moment the JsonLogic string produced is not the expected one.

As reported into the issue the expected string should be:

{
  "some": [
    {"var":"results"},
    {
      "and": [
        {
          "==": [
            {
              "var": "product"
            },
            "abc"
          ]
        },
        {
          ">": [
            {
              "var": "score"
            },
            8
          ]
        }
      ]
    }
  ]
}

Instead the produced string is:

{
  "and": [
    {
      "some": [
        [
          {
            "var": "results"
          }
        ],
        {
          "and": [
            {
              "==": [
                {
                  "var": "product"
                },
                "abc"
              ]
            },
            {
              ">": [
                {
                  "var": "score"
                },
                8
              ]
            }
          ]
        }
      ]
    }
  ]
}

As you can see the object {"var": "results"} is enclosed in an unexpected array.

@ukrbublik
Copy link
Owner

Are you sure removing square brackets will produce correct results when using "some" operation?
http://jsonlogic.com/operations.html#all-none-and-some
As for specs, there should be brackets

@Angelus1383
Copy link

Angelus1383 commented Sep 16, 2020

The square brackets shown in docs are around the data.
[-1, 0, 1] is the data array

If you scroll just a little bit down, you will find this example

{"some" : [ {"var":"pies"}, {"==":[{"var":"filling"}, "apple"]} ]}

{"pies":[
  {"filling":"pumpkin","temp":110},
  {"filling":"rhubarb","temp":210},
  {"filling":"apple","temp":310}
]}

The example in JsonLogic docs should be similar to the one in your demo for the results object, where:

  • pies is results,
  • filling is product
  • temp is score.

Here there aren't square brackets around {"var":"pies"}.

@ukrbublik
Copy link
Owner

In your example pies as array.
I made PR #273 to use "some" operator for nested data (!group).

This example works only with []

{
  "and": [
    { "some": [
      [ { "var": "results" } ],
      { ">": [  { "var": "score" },  15  ] }
    ] }
  ]
}
{
  "results": {
    "score": 16
  }
}

(http://jsonlogic.com/play.html)

@Angelus1383
Copy link

i understood your example, but in this case you have to put square brackets around results, in the JsonLogic rule, because results it's not an array, and you have to transform it. In JsonLogic all/some/none are operators to work with arrays, I think is not right to apply them to an object instead of an array.

With JsonLogic a rule like that is enough to achieve the same behavior of your example:

{ ">": [  { "var": "results.score" },  15  ] }

The external AND at the moment is pleonastic but it could be useful if you have to add other conditions

{
  "results": {
    "score": 16
  }
}

@ukrbublik
Copy link
Owner

I can make using 'some' for nested fields optional, configurable. PR is welcomed ;)

@dtsun-anduril
Copy link

dtsun-anduril commented Sep 25, 2020

Hi there! I am currently using react-awesome-query-builder for some internal tooling at my company, and am very pleased with the work that @ukrbublik and contributors have put in so far! However, I have come across this issue as well, and this is breaking one of our internal tools. It seems like @Angelus1383 has already taken the proper action to resolve this issue (thank you!), but I feel like this subtle issue deserves a more thorough explanation just to understand what exactly is being fixed.

If you look at the documentation of jsonLogic, it says "These operations take an array, and perform a test on each member of that array."

Expected Behavior

Let's look at what is being taken in for the two examples:

Example 1

{"some" : [ [-1,0,1], {">":[{"var":""}, 0]} ]}

Here, the first operand is an array. This evaluates to true.

Example 2

Logic:

{"some" : [ {"var":"pies"}, {"==":[{"var":"filling"}, "apple"]} ]}

Data:

{"pies":[
  {"filling": "pumpkin", "temp": 110},
  {"filling": "rhubarb", "temp": 210},
  {"filling": "apple", "temp": 310}
]}

Here, pies is being dereferenced such that the equivalent expression becomes:

{"some" : [
  [
    {"filling":"pumpkin","temp":110},
    {"filling":"rhubarb","temp":210},
    {"filling":"apple","temp":310}
  ], 
  {"==": [{"var":"filling"}, "apple"]} 
]}

which is a variant of Example 1. This also evaluates to true.

Generalized, some operates on an Array<T>, and queries on some property T.property. For this particular example, defining the following:

interface Pie {
    filling: string, 
    temp: number
}

some is operating on Array<Pie> and querying on Pie.filling.

Actual Behavior

react-awesome-query-builder will produce the following for Example 2:

{"some" : [ [{"var":"pies"}], {"==":[{"var":"filling"}, "apple"]} ]}

which will result in the equivalent expression:

{"some" : [
  [    
    [
      {"filling":"pumpkin","temp":110},
      {"filling":"rhubarb","temp":210},
      {"filling":"apple","temp":310}
    ]
  ], 
  {"==": [{"var":"filling"}, "apple"]} 
]}

Here, some is operating on Array<Array<Pie>> and is attempting to query on Array<Pie>.filling. Since Array<Pie> is not extended in any way to have the property filling, and is constrained to properties on Array.prototype, the == condition will never be satisfied. Thus, the current code will always evaluate to false. This is true for any type T.

@ukrbublik
Copy link
Owner

ukrbublik commented Oct 2, 2020

@Angelus1383 @dtsun-anduril I finally understood the root cause of issue and misunderstanding.
I missed that you are trying to use group fields as arrays.
Initially, I've developed !group support by request of some user and I thought that it will be used as alternative to !struct but just with another UI.

I'm preparing PR to fix this.

@mariojaros
Copy link

Hi there, is there any option to config export for !group type for sql format ?

@qazi9amaan
Copy link

Hi there, is there any option to config export for !group type for sql format ?

@mariojaros Did you found any way to export json fields in SQL?

@ukrbublik
Copy link
Owner

Please create a separate issue for SQL

@qazi9amaan
Copy link

qazi9amaan commented Jul 28, 2024

Please create a separate issue for SQL
Please find the newly created issue for SQL here:
#1101

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants