0

I have a query inside a function that is returning matches that i don't want, for example when the $id=116 it is also returning results where the meta_key 'funds_id' is 11687.

 public function list_related_docs($id){

    $docs_args = array(
        'post_type'     => 'publication',
        'post_status'   => 'publish',
        'posts_per_page'=> -1,
        'orderby'   => 'meta_value_num title',
        'order'     => 'ASC',
        'meta_key'  => 'fund_list_order',
        'limit'     => 4,
        'suppress_filters' => 0,
        'meta_query'    => array(
                                'relation'  => 'AND',
                                                array(
                                                    'key' => 'funds_id',
                                                    'value' => $id,
                                                    'compare' => 'LIKE'
                                                ),
                                                array(
                                                    'key' => 'fund_list_order',
                                                    'compare' => 'EXISTS',
                                                )
                                            )
        );
    $docs_posts = get_posts($docs_args);

   // more stuff
}

I've tried using 'compare' => '=' , but that doesn't return any results.

Thanks.

7
  • 'compare' => 'LIKE', note that 116 is 'like' 11687 as in they are similar
    – Tom J Nowell
    Commented Oct 20, 2014 at 23:51
  • Your comment on an answer implies that one or more of your meta values is not numeric, but is a serialised string. Can you confirm what the expected value of funds_id is in full and what data type it has? e.g. array, string, object, boolean, number, etc
    – Tom J Nowell
    Commented Oct 20, 2014 at 23:53
  • The $id would of course be an int(116) and the meta value of funds_id would be a longtext value - a:1:{i:0;s:3:"11687";}. I'm guessing the LIKE is matching '%116%', but '=' doesn't seem to return anything. I'm not clear if meta_key returns just the value 11687 or if there's a way to strip out the value.
    – jimlongo
    Commented Oct 21, 2014 at 4:46
  • Ah, = will never return what you expect because you're comparing and searching through PHP serialised strings, not raw values. Can I ask why you're not just storing the values rather than storing serialised data structures?
    – Tom J Nowell
    Commented Oct 21, 2014 at 16:39
  • It's a custom post type, therefore that seems to be the way the data is organized in the database.
    – jimlongo
    Commented Oct 21, 2014 at 17:04

2 Answers 2

1

Well, you need to include the type comparison, or alphanumeric comparison is applied here.

In this case, you should add 'type' => 'numeric'.

Using Your Class Function

<?php
public function list_related_docs($id){

            $docs_args = array(
                    'post_type'     => 'publication',
                    'post_status'   => 'publish',
                    'posts_per_page'=> -1,
                    'orderby'   => 'meta_value_num title',
                    'order'     => 'ASC',
                    'meta_key'  => 'fund_list_order',
                    'limit'     => 4,
                    'suppress_filters' => 0,
                    'meta_query'    => array(
                        'relation'  => 'AND',
                            array(
                                'key' => 'funds_id',
                                'value' => $id,
                                'compare' => '=',
                                'type' => 'numeric',
                            ),
                            array(
                                'key' => 'fund_list_order',
                                'compare' => 'EXISTS',
                            )
                        )
                    );
            $docs_posts = get_posts($docs_args);
            // more stuff
}
2
  • Thanks Courtney, I take it you're adding it in array before 'compare' => 'LIKE', when i do that it never returns any results. To be clear the meta value is a serialized array as it refers to a custom post type.
    – jimlongo
    Commented Oct 17, 2014 at 15:04
  • @jim - I've updated the answer above to include your function with the changes I mentioned. Commented Oct 20, 2014 at 23:39
0

A search through the plugin your code is based on indicates everything in your question is your own modifications.

The problem you face is that you're serialising PHP arrays and storing them in post meta, then attempting to run queries on them. This does not work, and never will work.

The example value you provided a:1:{i:0;s:3:"11687";} is equivalent to array( 11687 ). Instead of storing an array containing a single value, you should just store the number. If you need to store multiple numbers, you can have multiple post meta with the same key, or store them as a list in a separate post meta. But if you want to be able to run comparisons in SQL, or match against values, you can't use serialised data.

Once the data is stored as a number, not a serialised object, the answer Courtney gave will work. However Courtneys answer reasonably assumes it is a number not a serialised PHP string, as most other people assumed, hence why it did not work for you initially.

If you're using the ID purely for classification purposes, perhaps you could instead:

  • Set the post parent
  • Use a custom taxonomy where the ID is the term name

Otherwise, it is a general truism when working with databases that you don't store serialised structures in tables, especially if you then want to do queries on their contents.

1
  • Thanks Tom, this is a large project I've inherited. I wouldn't know why some things were done the way they were.
    – jimlongo
    Commented Oct 22, 2014 at 13:19

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.