spark85 / json-path

Automatically exported from code.google.com/p/json-path
0 stars 0 forks source link

Support for limiting the number of results #52

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Sometimes you only want to retrieve the first n results for a JsonPath 
expression. Currently that means that you have all results computed and just 
take the first n. It would be more efficient to only compute n results in the 
first place.

Original issue reported on code.google.com by foober...@gmail.com on 18 Sep 2014 at 8:27

GoogleCodeExporter commented 9 years ago
Any suggestions on API for this?

Original comment by kalle.st...@gmail.com on 1 Oct 2014 at 11:10

GoogleCodeExporter commented 9 years ago
I thought about that too. It might go into the Configuration class but that 
doesn't feel completely right. You could make it an Option, but as that's an 
enum, we could only toggle something like RETURN_ONLY_FIRST_MATCH. That would 
be enough for me, but it isn't very flexible. Maybe someone else wants to abort 
after the first 5 results.
Another option would be to make Option an interface, move the current Options 
to an Enum class that implements Option (e.g. DefaultOption) and add a 
LimitOption class that has a limit parameter. But that would mean that you have 
to implement a special handling for every Option implementation.
Of course, you could also just add a limit parameter to the relevant read 
methods in JsonPath, but that would increase the number of methods 
significantly.
I'm not sure which way is the best yet. What do you think?

Original comment by foober...@gmail.com on 1 Oct 2014 at 12:57

GoogleCodeExporter commented 9 years ago
There's another option: Make the whole evaluation lazy and return an Iterable. 
:-)
I'm not sure if that's feasible with the current code base, but I guess you'll 
eventually want to do this anyway.

Original comment by foober...@gmail.com on 1 Oct 2014 at 6:24

GoogleCodeExporter commented 9 years ago
Ah, wait, the result container is created using JsonProvider.createArray()... 
Hmm, you'd probably have to change that if you wanted to go down the lazy 
route. I guess that would be the nicest but also the most complicated option.

Original comment by foober...@gmail.com on 1 Oct 2014 at 6:27

GoogleCodeExporter commented 9 years ago
I just had a moderately crazy idea. I think I could create a custom 
JsonProvider that creates an array that shortcuts the execution after the first 
result...
I'll probably give that a try tomorrow. :-)

Original comment by foober...@gmail.com on 1 Oct 2014 at 6:35

GoogleCodeExporter commented 9 years ago
Yes, it actually works but the provider needs internal state now so I need a 
new instance for every evaluation. I don't like that very much, but I guess 
I'll do it that way nonetheless.
If I'm not mistaken, JsonPath does a depth-first search, so it should really 
save some time, at least if the tree is large and actually *has* a result that 
is close to the start.
That means the issue has a low priority for me, but I'd still like a clean 
approach to this. A listener approach would work too.

interface EvaluationListener {
  EvaluationContinuation resultFound(Object result){
    return EvaluationContinuation.ABORT; // to abort the execution
  }
}

I guess that would be fairly easy to add to the current implementation and 
would allow for quite some flexibility. Even a void listener method would help 
me, I could still throw a marker exception from the listener, that's what I do 
in my JsonProvider at the moment.

Original comment by foober...@gmail.com on 2 Oct 2014 at 7:28

GoogleCodeExporter commented 9 years ago
I like the EvaluationListener, as you say it's quite flexible. The question 
still remains how it should be specified. I agree that putting it in the 
Configuration does not feel completely right but it saves lots of method 
overloading. Maybe together with an API extension in the fluid API 

using(conf).parse(json).limit(1).read("$..foo");

Or we should have a set of new methods readAll(...) readFirst(...) on JsonPath. 
These would be easier to understand and use than the current Option approach.   

Original comment by kalle.st...@gmail.com on 6 Oct 2014 at 7:13

GoogleCodeExporter commented 9 years ago

Original comment by kalle.st...@gmail.com on 8 Oct 2014 at 6:33

GoogleCodeExporter commented 9 years ago
I like the `limit(int)` API. It's more flexible than `readFirst()` and 
`readAll()` (maybe someone wants only the first 10 results) and should be 
intuitive for most people who have seen SQL or the like before.

Original comment by foober...@gmail.com on 13 Oct 2014 at 7:25

GoogleCodeExporter commented 9 years ago

Original comment by kalle.st...@gmail.com on 8 Dec 2014 at 8:03