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

Support LINQ to JSONPATH querying #2570

Open
roji opened this issue Nov 20, 2022 · 8 comments
Open

Support LINQ to JSONPATH querying #2570

roji opened this issue Nov 20, 2022 · 8 comments
Labels
enhancement New feature or request performance
Milestone

Comments

@roji
Copy link
Member

roji commented Nov 20, 2022

It seems that JSONPATH support is very limited in other databases, and that PostgreSQL is the only one to support complex patterns, e.g.:

ctx.Entity.Where(e => e.JsonThing.Track.Segments.Any(s => s.HR > 130)
$.track.segments[*].HR ? (@ > 130)

See dotnet/efcore#28616 (comment) for more details.

We could set up a JSONPATH translation pipeline in EFCore.PG to support advanced querying inside JSON. If other databases develop this ability, we could move that to relational.

/cc @maumar @ajcvickers

Note #28824 which would provide raw JSONPATH string querying and #2669 which would translate JSONPATH APIs in System.Text.Json (if and when these are introduced)

@roji roji added the enhancement New feature or request label Nov 20, 2022
@roji roji added this to the 8.0.0 milestone Nov 20, 2022
@hahn-kev
Copy link

hahn-kev commented Mar 1, 2023

This would be awesome. But I'd also love support for calling jsonb_path_exists and providing my own path, that way if the translation doesn't work for my use case I can fallback to json path and write it myself without having to resort to writing raw sql.

@roji
Copy link
Member Author

roji commented Mar 1, 2023

@hahn-kev yeah, we definitely need raw JSONPATH APIs as well; this has been discussed. Opened #2668 to make sure this is tracked.

@NinoFloris
Copy link
Member

Fyi jsonpath does come with some constant cost perf penalties (due to the parsing and translating in pg), indices also won't be applied unless the entire path expression is a constant so that's a hard cliff to avoid too.

@roji
Copy link
Member Author

roji commented Jun 8, 2023

jsonpath does come with some constant cost perf penalties (due to the parsing and translating in pg)

Sure, but shouldn't that be taken care of by prepared statements as usual? I.e. is there anything special here compared to just normal SQL queries (beyond possibly a slightly higher constant perf cost)?

Fyi jsonpath does come with some constant cost perf penalties (due to the parsing and translating in pg), indices also won't be applied unless the entire path expression is a constant so that's a hard cliff to avoid too.

Yeah... The alternative to generating a JSONPATH query is to convert the JSON collection to a rowset (with jsonb_to_recordset) and then just use use regular SQL over that (BTW this is currently what I'm implementing in the EF JSON support - that should carry across to PG pretty transparently). Such a query might be a bit better, since it can be more properly parameterized: rather than concatenating some number into the JSONPATH string, you can e.g. use the parameter placeholder directly in SQL as usual. I'm guessing indexes wouldn't work after jsonb_to_recordset anyway, so I'm not sure this all matters.

What do you think?

@roji
Copy link
Member Author

roji commented Nov 15, 2023

Note that full LINQ querying has been implemented for version 8.0 of the provider, when using the newly supported EF ToJson() mapping (via owned entities). That approach uses jsonb_to_recordset to transform a JSON array into a relational table, and then uses the regular SQL mechanisms to query that table.

So while the need to support JSONPATH querying is now much lower, it may still make sense to convert certain complex queries over JSON to JSONPATH syntax, where that's possible. Beyond simplifying, this could be a sort of optimization in allowing an expression index to be defined for a particular JSONPATH expression - that's not likely to be possible with the complex SQL queries we produce now.

@roji roji modified the milestones: 8.0.0, Backlog Nov 15, 2023
@roji
Copy link
Member Author

roji commented May 15, 2024

Note that while we can definitely "simplify" at least certain translations to JSONPATH (instead of the current jsonb_to_recordset), the disadvantage is that if there's a parameter, we need to concatenate it into the JSONPATH string, which isn't great (and would presumably also prevent any sort of PG optimization, assuming that exists). If PG's JSONPATH supported some sort of parameterization, this would be more interesting.

(discussed with @NinoFloris)

@roji
Copy link
Member Author

roji commented Sep 28, 2024

Note that the new PG17 SQL/JSON now support parameterizing the jsonpath expression (JSON_VALUE(x, <pathexpression> PASSING (parameters), docs), so this becomes much more interesting.

@atrauzzi
Copy link

That's pretty awesome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request performance
Projects
None yet
Development

No branches or pull requests

4 participants