Home » Php » php – In Laravel/mySQL query, how to select users by comparing arrays (or how to incorporate array_diff in where clause)?

php – In Laravel/mySQL query, how to select users by comparing arrays (or how to incorporate array_diff in where clause)?

Posted by: admin February 25, 2020 Leave a comment

Questions:

Qn in simpler terms: I am searching as a user for other users. All users have set preferred languages and fluent languages. I need to select users whose fluent languages match with this user’s preferred languages. Both fluent languages and preferred languages are array (text fields in DB but through JSON cast). How to do that? (Also, fluent language is just one of many conditions in the query. So the query structure itself cannot be modified now.)

Details on what has been tried: I am getting a list of users into $users. One of the conditions require me to compare preferredLanguages (This is an array->collection1) with fluentLanguages (This is also is an array->collection2). All values of preferredLanguages needs to be present in fluentLanguage. So, I am using array_diff and checking if the result is null.

The issue is how do I use this within the where clause? I can use array_diff in, say, an if condition, but I don’t know to use it within the where clause.

I tried everything I can think of, but nothing works so far! Can someone please help?

$collection1=$preferrences->preferredLanguages;
$collection2='user_details.fluentLanguages';

$diff= array_diff($collection1, $collection1);

$users->where(function (Builder $query) use ($matchPref) {
        $query
           ->where($diff, '[]');  //I need to check if $diff is null/empty. I tried everything I can think of here. 
    });

Edit: I tried something else as siggested by Kenny below. I believe this might work but didnt quite solved it yet. Any help is appreciated.

$users->filter(function ($user, $key) use ($preferrences->preferredLanguages)){
            return ! array_diff($user['fluentLanguages'], $preferrences->preferredLanguages);
        });

I also tried with where but it did not work out as well.

$users->where(array_diff('user_details.fluentLanguages', $preferrences->preferredLanguages)->IsEmpty(), true)
How to&Answers:

One strategy that comes to my mind could be:

  1. Get the fluentLanguageof each user.
$candidates = User::select('id', 'fluentLanguage')->get();
  1. Filter them according to the condition.
$filtered = $candidates
                ->filter(function ($candidate, $key) use ($matchFluentIn) {
                    return ! array_diff($candidate['fluentLanguage'], $matchFluentIn);
                })
                ->pluck('id')
                ->all();
  1. Get full details of these filetered list of users:
$users = User::whereIn('id', $filtered)->get();

Hope this helps.