json-path / JsonPath

Java JsonPath implementation
Apache License 2.0
8.85k stars 1.63k forks source link

Aggregation function attempted to calculate value using empty array #191

Open transparentech opened 8 years ago

transparentech commented 8 years ago

In the 'store' example JSON, you can get a list of book prices using:

$.store.book[*].price

Or all prices:

$.store..price

What I tried to do is get the maximum price value using the max() function.

$.store..price.max()

However, this returns the error:

com.jayway.jsonpath.JsonPathException: Aggregation function attempted to calculate value using empty array

    at com.jayway.jsonpath.internal.function.numeric.AbstractAggregation.invoke(AbstractAggregation.java:62)
    at com.jayway.jsonpath.internal.path.FunctionPathToken.evaluate(FunctionPathToken.java:38)
    at com.jayway.jsonpath.internal.path.PathToken.handleObjectProperty(PathToken.java:81)
    at com.jayway.jsonpath.internal.path.PropertyPathToken.evaluate(PropertyPathToken.java:79)
    at com.jayway.jsonpath.internal.path.PathToken.handleArrayIndex(PathToken.java:133)
    at com.jayway.jsonpath.internal.path.WildcardPathToken.evaluate(WildcardPathToken.java:40)
    at com.jayway.jsonpath.internal.path.PathToken.handleObjectProperty(PathToken.java:81)
    at com.jayway.jsonpath.internal.path.PropertyPathToken.evaluate(PropertyPathToken.java:79)
    at com.jayway.jsonpath.internal.path.PathToken.handleObjectProperty(PathToken.java:81)
    at com.jayway.jsonpath.internal.path.PropertyPathToken.evaluate(PropertyPathToken.java:79)
    at com.jayway.jsonpath.internal.path.RootPathToken.evaluate(RootPathToken.java:62)
    at com.jayway.jsonpath.internal.path.CompiledPath.evaluate(CompiledPath.java:53)
    at com.jayway.jsonpath.internal.path.CompiledPath.evaluate(CompiledPath.java:61)
    at com.jayway.jsonpath.JsonPath.read(JsonPath.java:181)
    at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:164)
    at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:151)
    at com.jayway.jsonpath.JsonPath.read(JsonPath.java:502)

Is this a bug or is this type of function usage not yet supported?

I'm using the latest from 'master'.

jochenberger commented 8 years ago

168

kallestenflo commented 8 years ago

You are trying to apply the function max() to the result of the evaluation. That is not how things work. The function will be applied to each object matching the path. In your example max will be invoked on each price separately. I guessprice` is a number so your path is not correct.

I understand what you are trying to do but there is currently no support for running functions over a result set.

transparentech commented 8 years ago

Yes, the 'price' is a number. The queries above are based on the example JSON document in this project's README file.

What would it take to support running functions over a result set? Can you give some pointers in the code where I could start looking into adding this feature?

kallestenflo commented 8 years ago

First thing to do is define the syntax. How should this be expressed?

transparentech commented 8 years ago

See https://github.com/jayway/JsonPath/pull/197 for my proposal.

transparentech commented 8 years ago

The pull request, #197, is fully backwards compatible. All unit tests work. It allows you to use functions on evaluated arrays (result sets) rather than just static arrays.

See the usecases in ResultSetFunctionTest that use the example JSON document from the README file.

DaveParillo commented 7 years ago

I think that based on the documentation in the README, most people expect that if this works: $.max($.store.book[0].price, $.store.book[1].price, $.store.book[2].price, $.store.book[3].price) then this should also: $.max($.store.book[*].price)

drummerwolli commented 3 years ago

i know everyone dislikes these kind of comments, but any updates here? i just encountered this problem, so it's still an issue in 2021.

pwaksman973 commented 2 years ago

Same here, the possibility of this working would be super handy

$.sum($.products[?(@category = "categoryA")].value) or $.products[?(@category = "categoryA")].value.sum()

for the object

{
    "products": [
        {
            "category": "categoryA",
            "value": 157.12
        },
        {
            "category": "categoryA",
            "value": 11.99
        },
        {
            "category": "categoryB",
            "value": 55.99
        }
    ]
}
DaveParillo commented 2 years ago

@pwaksman973 - This does work. Your query is malformed. Try one of these on your object:

$.sum($..products[?(@.category == 'categoryA')].value)
$..products[?(@.category == 'categoryA')].value.sum()
JaysonGeng commented 2 years ago

I think that based on the documentation in the README, most people expect that if this works: $.max($.store.book[0].price, $.store.book[1].price, $.store.book[2].price, $.store.book[3].price) then this should also: $.max($.store.book[*].price)

thinks for u help

pbugga commented 2 years ago

We are trying to upgrade from json-path 2.3 version to 2.7 and run into this issue.

Following is the JSON

{
 "response": {
  "dates": ["2016-04-19T00:00:00",
  "2016-04-19T01:00:00",
  "2016-04-19T02:00:00",
  "2016-04-19T03:00:00",
  "2016-04-19T04:00:00",
  "2016-04-19T05:00:00",
  "2016-04-19T06:00:00",
  "2016-04-19T07:00:00",
  "2016-04-19T08:00:00"],
  "data": [1,2,3,4,5,6,7,8.1999999999999318,9.019999999999981]
 }
}

Running $..data.min() gives following Exception Caused by: com.jayway.jsonpath.JsonPathException: Aggregation function attempted to calculate value using empty array at com.jayway.jsonpath.internal.function.numeric.AbstractAggregation.invoke(AbstractAggregation.java:59) ~[json-path-2.7.0.jar:2.7.0] at com.jayway.jsonpath.internal.path.FunctionPathToken.evaluate(FunctionPathToken.java:40) ~[json-path-2.7.0.jar:2.7.0] at com.jayway.jsonpath.internal.path.RootPathToken.evaluate(RootPathToken.java:66) ~[json-path-2.7.0.jar:2.7.0] at com.jayway.jsonpath.internal.path.CompiledPath.evaluate(CompiledPath.java:99) ~[json-path-2.7.0.jar:2.7.0] at com.jayway.jsonpath.internal.path.CompiledPath.evaluate(CompiledPath.java:107) ~[json-path-2.7.0.jar:2.7.0] at com.jayway.jsonpath.JsonPath.read(JsonPath.java:179) ~[json-path-2.7.0.jar:2.7.0] at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:88) ~[json-path-2.7.0.jar:2.7.0] at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:77) ~[json-path-2.7.0.jar:2.7.0]

suhailSj commented 4 months ago

We are also facing similar issue, max is not working however min and avg seems to be working the same data.