Closed alexdemers closed 9 months ago
To add performance benchmarks, considering my user_fileables_tree
has ~120k rows on my development machine (production is millions of rows), adding constraints to the end query takes ~1.2 seconds on average and having them in the initial query and recursive query takes about 0.02s (20ms).
Hi @alexdemers,
I know there's a static::$recursiveQueryConstraint that you can assign, but it's not per-query based, it's a global constraint.
The constraint can be global, but with it's only applied to a single query typically: https://github.com/staudenmeir/laravel-adjacency-list?tab=readme-ov-file#graphs-recursive-query-constraints
Nevertheless, it's actually not possible to add the constraint to the initial query in your particular case. I've already been working on the missing feature and I'll prioritize it.
Thanks for sharing the benchmark.
I've released a new version with withQueryConstraint()
that allows you to add a constraint to both the initial and the recursive query:
https://github.com/staudenmeir/laravel-adjacency-list?tab=readme-ov-file#graphs-initial--recursive-query-constraints
$parents = Folder::withQueryConstraint(function (Builder $query) use ($user) {
$query->where('user_fileables_tree.user_id', $user->getKey());
}, function () use ($folder) {
return $folder->parents;
});
Thank you very much, I'll try this out! This library really helps me query my hierarchy without having to rewrite the table structure! Great work!
This works for per-query basis, but how can I integrate this for relationships? What would be nice is:
$folders->descendants()
->withQueryConstraint(fn($query) => $query->where('user_fileables_tree.user_id', $user->getKey());
Due to the way Laravel relationships work, that's not possible, unfortunately.
I discovered this library for hopefully switch all of our tree queries to use MySQL's with expressions using this library. For our use, we have a tree of files and folders for every user of our application.
The code works, but it is not optimized for performance. The added constraint for the user id is added at the end. I want to add it to the initial query and the recursive query.
Basic structure
user_fileables_tree
Models/Folder.php
main.php
Executed query
(see comments in the query)
I tried adding
subgraph(fn($query) => $query->where("pivot_user_id", $user->getKey()))
to myancestors()
relationship but it adds another query to the with expression as shown below, which errors out because there are 2 tables namedlaravel_cte
:I know there's a
static::$recursiveQueryConstraint
that you can assign, but it's not per-query based, it's a global constraint.So basically my question is: how do I add constraints to the initial query and the recursive query without adding them to the "end" query to optimize performance? I wish a
whereInitial($constraint)
andwhereRecursive($constraint)
would exist. Maybe I'm missing out on something obvious but I've read through the docs and code...