0

I'm using the rest_photo_query filter to manipulate the arguments of WP_Query through the use of my own GET parameters. It's working perfectly and fast, with one exception.

I can adjust the orderby parameter using rest_sht_photo_collection_params, and it's easy to sort the results by meta_value.

The photo Custom Post Type entries are connected to a second Custom Post Type species by means of the species_id.

I need to be able to sort the photo posts by species title.

Does anyone have a good idea how to achieve this? As I'm modifying the WP_Query in a standard endpoint, my preference would be to modify the WP_Query arguments somehow.

I've tried building my own query in a custom endpoint and then modifying the resultant array by looping through it, but this makes the request about 100x slower.

Here's a partial example of a simpler field, where the custom orderby my_custom_meta_field is added as a meta_value comparison:

switch ($args['orderby']) {
    case 'my_custom_meta_field':
        $args['orderby'] = 'meta_value';
        $args['meta_key'] = 'my_custom_meta_field';
        break;
9
  • Is it not possible in js? The database won't know that the meta value is a post id, just that it's a number value. Making it then look up that post and do sorting would make it an extreme performance hit. You may find that it takes multiple seconds ( double digits ) to run in production and can only be ran once or twice in parallel without database issues. This isn't something WP_Query can do, and adding levels of indirectness is not something you want to do
    – Tom J Nowell
    Commented Mar 24, 2021 at 13:29
  • JS based sorting should be more scalable and faster for all parts, and could be thousands of times faster
    – Tom J Nowell
    Commented Mar 24, 2021 at 13:31
  • I see what you mean, but the data set needs to be pre-sorted and pre-filtered (there is a meta_query in there too). Otherwise the pagination doesn't work. We're talking about nearly 10,000 posts, so I can't send them all to the frontend and let the browser handle the filtering and sorting. Commented Mar 24, 2021 at 13:57
  • Then you're going to have to store the title on the post in the meta. What's the context behind this? It's an unusual request. Would it not make sense to fetch a list of species then fetch posts for each species in order and using the species totals count to figure out pagination? The posts first approach is going to be extremely expensive. You're going to want to invest in a lot of caching at multiple levels to make it work at any kind of scale ( think more than a handful of concurrent users/requests )
    – Tom J Nowell
    Commented Mar 24, 2021 at 15:43
  • Yes, that's exactly what I did with the custom endpoint. However, the REST response sometimes took nearly 30 seconds to deliver 25 results, which is obviously unacceptable. The regular endpoint comes back in 250ms, even with filtered and sorted data, and everything is done except for this one sort option. I may have to solve it by pre-storing a value against the post; as you said, potentially with a meta entry. Commented Mar 24, 2021 at 16:29

2 Answers 2

0

You can't, WP_Query can sort by post meta value, but it can't then use that value as a post ID, look up that post, then sort by a value on that other post.

If you had a small number of posts, it could be done by manually sorting the results with PHP.

Fundamentally, the data is not stored in a way that makes this feasible.

0
0

I solved the problem by adding a custom post meta value to each photo, containing the species name, then ensuring that the meta is up-to-date by using save_post hooks on the photo and species. The query now works as required and returns the data I need in around 100ms. This means that I can continue to use this solution without having to use JavaScript.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.