Skip to content

Support wildcard (*) in stache querybuilder where queries #7454

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

Conversation

ryanmitchell
Copy link
Contributor

One thing I find myself reaching for a lot, and that has also been asked for on Discord a few times, is the ability to query inside replicator type fields (indexed arrays) for a subfield value.

At the moment you can do the following:

$query->where('replicator_field->0->sub_field', 1)
->orWhere('replicator_field->1->sub_field', 1);

Obviously this falls apart when you dont know the length of your replicator field, or becomes unwieldy when you have lots of items in your replicator as you have to write lots of orWheres()

The PR attempts to resolve this by supporting wildcard searches (*) in where queries.

So the query above would become:

$query->where('replicator_field->*->sub_field', 1);

As far as I can tell, compatibility with eloquent will not be possible for this feature, so it would be file-driver only.

You'll see from the code I've restricted this to arrays only, though you may want to widen the scope once you see it in action. I've also tried to accommodate multiple wildcards... eg

$query->where('replicator_field->*->sub_field->*->value', 1);

@what-the-diff
Copy link

what-the-diff bot commented Feb 2, 2023

  • Added wildcard support to the where() method.
  • Fixed a bug in the resolveItemPartValue() function that was causing it to return null when an array key didn't exist, even if there were more keys left in $nameExploded (the variable name is misleading). This caused issues with nested arrays and json fields not being found correctly.
  • Changed some of the tests for clarity/readability purposes only - no functional changes here!

@jasonvarga
Copy link
Member

jasonvarga commented May 29, 2023

Just thinking aloud here.

If we were to try and make this comparable to Eloquent, which I would prefer to do in most cases, you could think of your replicator field as a relationship where its rows live in a separate table.

$query->whereHas('replicator_field', function ($query) {
  $query->where('sub_field', 'value');
});

That's a huge can of worms though, so your solution will probably be the way, at least in the mean time.

@ryanmitchell
Copy link
Contributor Author

Yeah I dont love that theres no eloquent equivalent.
Maybe this is just a bad idea.

@ryanmitchell
Copy link
Contributor Author

ryanmitchell commented Jul 21, 2023

If you like #8476 it might be possible to extend it to do this now. We would just need to make a query builder for replicator fields (probably ItemQueryBuilder)

@jasonvarga
Copy link
Member

Nice. I'd prefer that if possible. Let's put this on the backburner until #8476 gets sorted out then we can revisit this.

@jasonvarga jasonvarga closed this Jul 24, 2023
@ryanmitchell
Copy link
Contributor Author

I've taken a quick look at it and I think a combination of the two PRs is necessary and would be eloquent compatible.

So you would end up with queries like

$query->whereHas('replicator_field', function ($subquery) {
   $subquery->where('*->sub_field->*->value');
});

To explain why it would now work on eloquent - the whereHas() gets the matching data, the 'subquery' clause filters it using an ItemQueryBuilder so the */wildcard no longer needs to be eloquent compatible.

If we were to try to go down the whereHas route entirely, you'd end up back at the original problem with queries like:

$query->whereHas('replicator_field', function ($subquery) {
   $subquery->where('0->sub_field->0->value');
});

or some deep deep nesting of whereHas which will get mucky from a DX point of view.

Anyway, as you said lets loop back if #8476 gets merged and we can go from there.

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

Successfully merging this pull request may close these issues.

2 participants