12 thoughts on “Post Meta Abuse

  1. Super interesting post, thank you!

    I must admit, up until now I used to only consider taxonomies whenever the data I wanted to save was very similar to categories or tags. For everything else, I used post meta. I’ll try to change that!

    I have a few questions, though:

    1) What do you do for post meta that is usually saved as an array, with multiple values? This little plugin of mine for example stores 2 different colours for each post. Would you suggest creating 2 different taxonomies?

    2) It’s relatively easy to create custom meta boxes in the admin, allowing one to create user-friendly input fields for custom meta data. To take the example above, I add a colour picker to the post editor. What do you do when data has to be saved as a taxonomy term?

    • Thanks 😀

      1) I must admit, exact hex or RGB value colours don’t lend themselves to terms, you’d end up with hundreds of terms that have a single post, so it’s a case of precision and use case.

      The same is true of prices, you wouldn’t search for $4.98, but you might want to show all products between $1 and $5. I’d do this by adding a price range taxonomy, defining my terms as buckets, then putting products in each bucket when they’re saved/updated.

      The same strategy might work for colours, but you’d need some rules about how to define those buckets.

      But if on the other hand you mean an example of ‘red & blue’ or ‘green & orange’, I’d have a non-hierarchical taxonomy and use a tax_query to filter.

      TLDR: Store it as a post meta for precision when displaying on the page or doing calculations, but store a more general version as a term that you can filter on for searching and browsing

      2) While I’m not sure that the data a colour picker generates is best stored in a term, creating a metabox should be just as easy as post meta but using `wp_set_post_terms` etc instead.

      Admittedly people have had a lot more time and incentive to build meta box frameworks, but one of the more popular and well tested/scalable frameworks Field Manager by Alley Interactive supports this. When defining a field, tell it to use a term datasource object. Coincidentally there’s a Colourpicker field.

  2. Indexes on meta_value won’t really help with WP_Query, because internally WordPress does CAST(), which needs to read and convert all values, before filtering any of them out, which means the index can’t really be used, unless you hack into the generated queries and try to strip away the CAST(), in which case you may have other problems when working with numeric values.

    Also surprised you haven’t mentioned Elasticsearch on Sphinx. That would go under a “Not so easy fix” heading, but once it’s all set up, it works like a charm, especially with 10up’s ElasticPress plugin.

  3. So from reading both yours and Alex’s articles, would it be right to say that it’s fine to use custom fields (post meta) for elements on a page which won’t be searched for – ie Phone Number, Gallery, link to external website, Google Map etc? But then to use custom taxonomies for elements which will be queried – ie to display all posts which are “Self Catering or B&Bs”, “Dogs Welcome/Not Welcome” or “Has Wifi”?

  4. Hi Tom,

    This is the kind of posts I LOVE to read, just perfect for people like me = not developers, but able to understand when explained clearly 🙂 and I also like the fact that the “you shouldn’t” is followed by the “why” … thanks a lot!

    Are you on your gravatar with Finnish’ Moominpappa? If yes, I must friend you somewhere on social networks absolutely 😉

    Cheers!

  5. Great post Tom. Both eye opening and frustrating in equal measure, as the more performant solution is right under our noses!

  6. Great timing of this post – it made me realise I should be using a taxonomy instead of custom field for a project I’m working on at this very moment, and inspired me to optimize another query to be way less complex. Thank you! 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *