query to find “parent” posts of CPT A while filtering “child” posts of CPT B

These meta queries are going to be expensive, and figuring out the answer and caching it is a poor solution, so why not go to the root of the problem and adjust the data structure?

Your core data type is the restaurant, and you want to filter/query so that means taxonomies, so why not have a Location/city taxonomy? Just because you have a city post type doesn’t mean you can’t also add a city or area taxonomy. Structure it hierarchically via continent -> country -> province -> city.

Now your search is a search of restaurants with a tax_query that specifies the city. Do this for every child term in a province/country and you have what you want.

As an aside, this still doesn’t avoid meta queries, which are the number 1 performance issue you’ll face by a huge margin. Anything you currently store as post meta that you’re going to let users filter or search by needs to be a taxonomy, or have an equivalent. E.g. for Prices you might lay out ranges of “€10-20 per person” etc, then let users search by this instead of entering a precise value.

So the end result will give you:

  • A page that when given a term in the location taxonomy, grabs the deepest child terms, then loops over them
  • For each of these child terms it
    • Queries for restaurants in that term that match the other search parameters, with a max of 4 or 5 restaurants for performance reasons
    • If any are found
      • Displays the title of the term/city
      • Displays the results of the search and a link to a full results page

I’d also advise the following things:

  • Use pre_get_posts, this will give you pagination for free, just put the search UI at the top of the template, if you can use the taxonomy archive for the cities/location taxonomy then even better!
  • Taxonomies taxonomies taxonomies taxonomies, don’t use post meta queries. If you do the scalability and performance of this page will fall of dramatically. A single meta query can bring down a site with heavy traffic, if you’re doing one for each city here then this page will take a long time to load

Finally, consider that just because you can query this, doesn’t mean you should. For an efficient data structure with fast page loads, you need to decide what constraints are acceptable. The more freeform your data is the more expensive your queries will be, or the more data you need to duplicate and approximate. At some point you’ll need Elastic Search to attain even mediocre performance if you want to be able to query anything.

Make UX decisions to change what a user can search for in ways that help you but don’t deny the user what they want. E.g. letting the user pick a predefined price range or ranges, rather than giving them an entry box that accepts any number ( sliders can snap to the closest €5, turning a pricy meta query into a faster taxonomy query that mentions multiple terms )

Leave a Comment