php WordPress 元查询数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18036471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 16:50:53  来源:igfitidea点击:

WordPress Meta Query Arrays

phpmysqlwordpressserializationmetadata

提问by Drew Baker

I'm building a way form my users to "like" a post.

我正在建立一种让我的用户“喜欢”帖子的方式。

I'll have an array of users that have liked posts:

我将有一系列喜欢帖子的用户:

$user_ids = array(60, 61, 62, 63);

And then a post will have a post_meta that saves the user ID when the "like" button is clicked on a post, like so:

然后一个帖子将有一个 post_meta ,当点击一个帖子的“喜欢”按钮时,它会保存用户 ID,如下所示:

// Build array of user IDs that have liked this post
$likes = array(61, 62);

// Save array
update_post_meta($post->ID, likes, $likes);

So how can I return all posts liked by the users. This is how I'm doing it currently, which doesn't work.

那么我怎样才能返回用户喜欢的所有帖子。这就是我目前的做法,这不起作用。

$args = array(
    'post_type'         => 'post',
    'post_status'       => 'publish',
    'posts_per_page'    => -1,
    'orderby'           => 'rand',
    'meta_query'        => array(
        'relation'  => 'AND',
        array(
            'key'       => 'likes',
            'value'     => $user_ids,
            'compare'   => 'IN'
        )
    )
);
$posts = get_posts($args);

This should return all posts that have '60, 61, 62, 63' saved in the posts 'likes' meta. But it returns 0 results.

这应该返回在帖子“喜欢”元中保存了“60、61、62、63”的所有帖子。但它返回 0 结果。

Now, I think this is because WordPress serializes arrays when they are saved in a post_meta.

现在,我认为这是因为 WordPress 在将数组保存在 post_meta 中时会对其进行序列化。

So, how do I a do a query like this? Is it even possible? Maybe I have to use the $wpdb class.

那么,我该如何做这样的查询呢?甚至有可能吗?也许我必须使用 $wpdb 类。

Thanks!

谢谢!

回答by M Khalid Junaid

Try this one with WP_Queryno need of relation just use the compare part with IN

试试这个WP_Query不需要关系的只是使用比较部分IN

 $user_ids = array(60, 61, 62, 63);
 $args = array(
   'post_type' => 'post',
   'meta_key' => 'likes',
   'post_status'       => 'publish',
   'posts_per_page'    => -1,
   'orderby'           => 'rand',       
   'order' => 'ASC',
   'meta_query' => array(
       array(
           'key' => 'likes',
           'value' => $user_ids, //array
           'compare' => 'IN',
       )
   )
 );
 $query = new WP_Query($args);

See the given example above "Time Parameters" Heading WP_Query

请参阅上面给出的示例“时间参数”标题WP_Query

OR by get_posts try this

或者通过 get_posts 试试这个

$args = array(
    'post_type'         => 'post',
    'post_status'       => 'publish',
    'posts_per_page'    => -1,
    'orderby'           => 'rand',
    'meta_query'        => array(

        array(
            'key'       => 'likes',
            'value'     => $user_ids,
            'compare'   => 'IN'
        )
    )
);
$posts = get_posts($args);

OR by a custom query you can do as follows

或通过自定义查询,您可以执行以下操作

global $wpdb;

$liked_posts=$wpdb->get_results("SELECT * FROM `wp_posts` WHERE 
post_type='post' AND post_status ='publish' AND ID
 IN(
SELECT post_id FROM `wp_postmeta` WHERE meta_key='likes' 
AND meta_value IN (".join(',',$user_ids).")
) ORDER BY RAND()");

Also don't store array of ids in one row instead loop through ids array and normalizeyour likes data manually Don't serialize data into a database field. That's what Database_normalizationis for and insert each id in new row because

也不要将id 数组存储在一行中,而是循环遍历 ids 数组并手动标准化您的喜欢数据 不要将数据序列化到数据库字段中。这就是Database_normalization的用途,并将每个 id 插入新行,因为

Wordpress stores the meta values as strings. When you pass update_post_metaan array, it automatically converts it to a string. What you'll need to do is unserializeit when you attempt to read the data but in mysql you can't unserializecolumn data in the query because mysql doesn't about the serialization of php

Wordpress 将元值存储为字符串。当您传递 update_post_meta数组时,它会自动将其转换为字符串。unserialize当您尝试读取数据时,您需要做的是,但在 mysql 中,您不能unserialize在查询中列数据,因为 mysql 与 php 的序列化无关

$likes = array(61, 62);

foerach($likes as $l){

update_post_meta($post->ID, "likes", $l);

}

And below is the query you have asked for in bounty comments

以下是您在赏金评论中要求的查询

If a $wpdb answer is given, then please elaborate on how to factor in category (include and exclude), and ignore posts by an array of IDs

如果给出了 $wpdb 答案,那么请详细说明如何考虑类别(包括和排除),并通过一组 ID 忽略帖子

$liked_posts=$wpdb->get_results("
SELECT * FROM `wp_posts` wp
INNER JOIN `wp_term_relationships` wtr ON (wp.`ID`=wtr.`object_id`)
INNER JOIN  `wp_term_taxonomy` wtt ON (wtr.`term_taxonomy_id` =wtt.`term_taxonomy_id`)
WHERE  wp.post_type='post' AND wp.post_status ='publish' AND wp.ID
 IN(
SELECT post_id FROM `wp_postmeta` WHERE meta_key='likes' 
AND meta_value IN (".join(',',$user_ids).")
)  AND wp.ID NOT IN (100,101,102)
AND wtt.`term_id` IN(1,2,3) AND wtt.`term_id` NOT IN (4,5,6,)    
ORDER BY RAND() ");

I have used the INNER JOINson wp_term_relationshipsand wp_term_taxonomythe table wp_term_relationshipsstores the relation of posts and the taxonomy of category and the table wp_term_taxonomyhave the taxonomy of the category and also the category id

我使用了INNER JOINsonwp_term_relationshipswp_term_taxonomytablewp_term_relationships存储了帖子的关系和类别的分类法,并且表wp_term_taxonomy有类别的分类法和类别 id

Here is the part which covers the

这是涵盖的部分

1. category (include and exclude)

1. 类别(包括和排除)

AND wtt.`term_id` IN(1,2,3) AND wtt.`term_id` NOT IN (4,5,6,) 

2. ignore posts by an array of IDs

2. 通过一组 ID 忽略帖子

AND wp.ID NOT IN (100,101,102) 
or $postids =array(100,101,102);
AND wp.ID NOT IN (".join(',',$postids).")

回答by wunderdojo

You're going to run into problems with your current approach because, as you note, the ids are saved as serialized arrays in a single field. An easier approach would be to save each like as a single postmeta entry. So meta_key = "like" and meta_value = user ID.

您将遇到当前方法的问题,因为正如您所注意到的,id 被保存为单个字段中的序列化数组。一种更简单的方法是将每个赞保存为单个 postmeta 条目。所以 meta_key = "like" 和 meta_value = 用户 ID。

So for storing the likes switch from update_post_meta to add_post_meta:

因此,为了存储喜欢从 update_post_meta 切换到 add_post_meta:

/** The fourth parameter, false, tells WP that there can be multiple
  * post_meta entries with the same meta_key. It's false by default, just here
  * here for reference
  */
add_post_meta($post->ID, 'like', $user_id, false);

Then to get posts liked by a specific user you would just do:

然后要获得特定用户喜欢的帖子,您只需执行以下操作:

$liked_posts = $wpdb->get_results("SELECT post_id FROM {$wpdb->prefix}postmeta 
              WHERE meta_key = 'like' AND meta_value = $user_id");

To get results for a number of users at once, like user ID 4, 23, 39, etc.

一次获取多个用户的结果,例如用户 ID 4、23、39 等。

$liked_posts_by_user = $wpdb->get_results("SELECT meta_value as user_id, 
         GROUP_CONCAT(post_id) as posts FROM {$wpdb->prefix}wp_postmeta 
         WHERE meta_value IN('22','23','24') GROUP BY user_id

That will give you results like:

这会给你这样的结果:

  user_id    posts
   23         1
   25         2,40,3

So just replace the IN portion of the query with your array of user ids.

因此,只需将查询的 IN 部分替换为您的用户 ID 数组。

回答by yunieski dieguez garcia

I had a similar problem and i solved it using the serialize(), you can use ir in case that the vale you are working with is an integer here′s my example:

我有一个类似的问题,我使用 serialize() 解决了它,如果你正在使用的 vale 是一个整数,你可以使用 ir,这是我的例子:

    $args = array(
    'meta_query' => array(
        array(
            'key' => 'my_meta_key',
            'value' => serialize(strval($my_id)),
            'compare' => 'LIKE'
        )
    )
);
$posts = get_posts( $args );

and that′s all, you hace your meta query ready.

这就是全部,您准备好元查询。

回答by Mangesh Parte

Your query is right. But as you are storing user ids as a string your query wont work. Save user id a single meta value for post.

你的查询是对的。但是当您将用户 ID 存储为字符串时,您的查询将不起作用。将用户 ID 保存为单个元值以供发布。

add_post_meta($post->ID, 'like', $user_id, false);

and replace 'compare' => 'IN'with 'compare' => 'LIKE'

并替换'compare' => 'IN''compare' => 'LIKE'