WordPress, fetching users with an exact match in a string of comma separated values in user_meta

You can’t do this in a query with that kind of data.

The only way to truly do it is to retrieve all users, and manually process them in PHP to find the ID. Otherwise, you will get false positives such as the example you gave.

The fundamental problem, is the way the data is stored. There are several other options:

  • store each areapref as an individual key/value pair, remember meta keys are not unique, you can add multiple values with the same key. Just set the 3rd parameter of get_user_meta to false and it will return an array of them instead of a single value.
  • a taxonomy, taxonomy terms are used for posts by tracking their post ID, but they can be used for any kind of ID. Comment Category, User Tags, are both valid taxonomies, and it’s perfectly valid to pass user as the second parameter when calling register_taxonomy, just be warned some additional boilerplate is necessary to get a WP Admin UI ( see Justin Tadlocks article on user taxonomies for code )

If you use individual user meta, your get_users call ( actually a WP_User_Query wrapped in a middle man helper function ), will be a lot more straight forward.

If you use a user taxonomy, then you’ll also see a significant performance and scalability improvement. Meta is optimised in the database for queries where you already know the post/user ID. The meta tables have awful performance when doing searches and filtering. You would use all the same methods to retrieve the users that you would when retrieving post terms aka get_terms to retrieve the terms that match that location, where the terms all have a slug that matches a column in the em_locations table, then get_objects_in_term to retrieve the user IDs.

I realise you may have coded yourself into a tight corner by relinquishing control to frameworks such as ACF for your core data storage. Those frameworks usually provide filters that can help change how data is stored and retrieved for fields, but you will need to ask in an ACF community for help with that.

Additionally, you will need to migrate your data. This should be relatively easy, just create a loop that fetches 50 users that have that user meta set, create the new data for those users, delete the old meta that you queried for, then reload the page until it says it can find none.