Question

I'm starting to develop an Worpdress portal with cca 5000 users. Each of the users will have cca 20 meta values (like street, city etc.).

I would need to do some reports with pagination / sorting on the users metadata, and I'm curious what would be the most efficient approach to take.

Wordpress normally stores each meta in usermeta table, so I might either:

1) join the users and usermeta table multiple times, to get all the metadata, and sort in the MYSQL query directly

2) use get_users(array('fields' => 'all_with_meta')); and custom sort function as described here http://www.stormconsultancy.co.uk/blog/development/code-snippets/sort-a-list-of-wordpress-users-by-a-custom-meta-field/

3) create custom meta table to store the values - described here http://sltaylor.co.uk/blog/custom-meta-tables-wordpress/

What would be the best approach to take? Or are there any other ways to work with users and their metadata in Wordpress?

Was it helpful?

Solution

I had a similar question yesterday for a system that searches specific postmeta fields for keywords.

The answer on the link above will return the post if any of the fields contain the search term.

However, an improved version below returns how many of the keywords were found (between 0 and # of keywords, NOT the actual count of keywords found in each field).

FYI Post meta and user meta tables are basically the same thing, this should work for you. You might be able to set this up using a wordpress query object, however my code is custom SQL as it is a standalone script - outside of WordPress.

SELECT *

FROM (
  SELECT
    post.ID as post_id,

    ( IF ( (
      post.post_title LIKE '%c++%'
      OR post.post_content LIKE '%c++%'
      OR meta_field_a.meta_value LIKE '%c++%'
      OR meta_field_b.meta_value LIKE '%c++%'
   ), 1, 0 )
    + IF ( (
      post.post_title LIKE '%java%'
      OR post.post_content LIKE '%java%'
      OR meta_field_a.meta_value LIKE '%java%'
      OR meta_field_b.meta_value LIKE '%java%'
   ), 1, 0 ) ) AS occurrences

  FROM wp_posts post

  JOIN wp_postmeta meta_field_a ON ( meta_field_a.post_id = post.ID AND meta_field_a.meta_key = 'field_a' )
  JOIN wp_postmeta meta_field_b ON ( meta_field_b.post_id = post.ID AND meta_field_b.meta_key = 'field_b' )

  WHERE post.ID IN (212, 213, 214)

  GROUP BY post.ID
) AS results

WHERE results.occurrences > 0

The "IF" statement blocks are checking for the keyword, and return 1 or 0 if they are found or not found (in any field). This is added together to produce "occurrences", which is returned per-row.

The "JOIN" statement block is pulling in a single meta by key name. Every meta key needs it's own join, but apparently that is not an expensive operation.

The "WHERE" statement is restricting the filter to specified post IDs. These come from an external function, but you can replace that with your own where statement to check the post type/status manually. Since you're dealing with users, though, you probably don't want the WHERE in there at all (or maybe you want to check other user meta, such as role).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top