基于月份的元查询,而不考虑年份

时间:2020-07-23 作者:Dor

对于我网站上的每个用户,我使用ACF日期字段(存储为YYYYMMDD)存储生日。有没有一种方法可以构造一个元查询来检索所有在特定月份生日的用户,而不考虑年份?

2 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

regexp 解决方案将发挥作用,随着用户数量的增加,速度会很快变慢。这是因为数据库无法执行优化和索引技巧,并强制进行全表扫描。用户越多,元越多,查询的成本就越高。至少是这样requires 缓存以避免出现最坏情况。

所有元都是如此,无论是帖子元、评论元、术语元还是用户元。通过元的内容来搜索东西是非常昂贵的。

但这是可以避免的。

除了将数据存储在用户元密钥/值对中之外,还要注册一个私有/非公共自定义分类法。当用户保存其配置文件时,在此分类法中使用月份作为值为该用户设置一个术语。

然后,您可以使用超快速查询来获取该月份的用户。

首先,注册专用用户分类:

function hidden_user_taxonomies() {
    register_taxonomy( \'birthday_months\', \'user\', [
        \'label\'        => __( \'Birthday Months\', \'textdomain\' ),
        \'public\'       => false
        \'hierarchical\' => false,
    ] );
}
add_action( \'init\', \'hidden_user_taxonomies\', 0 );
请注意,此处的对象类型不是post类型,而是user, 还有那个public 设置为false.

然后,我们连接到user profile save,并为该用户设置术语:


add_action( \'personal_options_update\', \'save_hidden_birthday_month\' );
add_action( \'edit_user_profile_update\', \'save_hidden_birthday_month\' );

function save_hidden_birthday_month( $user_id ) {
    $birthday = get_field( \'birthday field name\' );
    $month = ... get the birthday month out of the string....
    wp_set_object_terms( $user_id, [ strval( $month ) ], \'birthday_months\', false );
}
现在,我们有了一个隐藏的用户分类法,其中包含一年中每个月的术语,当用户的概要文件更新时,会将用户分配到这些月份。还要注意intval 打电话,这就是我们要存储的4 而不是04.

那么我们如何获取用户呢?简单:

function users_in_birthday_month( $month ) : array {
    // fetch the month term
    $month = get_term_by( \'name\', $month, \'birthday_months\' ); // who has birthdays in July?
    if ( !$month ) {
        // nobody has a month in July as there is no term for July yet
        return [];
    }
    // fetch the user IDs for that month
    $user_ids = get_objects_in_term( $month->term_id, \'birthday_months\' );
    if ( empty( $user_ids ) ) {
        // there were no users in that month :(
        return [];
    }
    $user_query = new WP_User_Query( [
        \'include\' => $user_ids,
    ] );
    return $user_query->get_results();
}
那么要让所有用户在7月份过生日呢?

$july_birthdays = users_in_birthday_month( 7 );
foreach ( $july_birthdays as $user ) {
    // output user display name
}
如果要显示完整的生日,只需获取原始的post元字段。

这意味着:

您现在可以使用超快的分类查询

  • 随着用户基数的增长,您的查询不会以指数级的速度变慢。此数据非常容易缓存,如果使用对象缓存,则会获得更多性能提升。只有12个可能的查询需要缓存
  • 您可以将其扩展为包括月份的天数、年份等,可能需要从$_POST 而不是get_field 由于ACF可能尚未保存价值,请记住,不要使用meta来搜索内容,这就是术语和分类法的创建目的。

    帖子并不是唯一可以有分类法和meta的东西,有关用户分类法的更多信息,see this helpful article from Justin Tadlock.

  • SO网友:mozboz

    如果该字段明确存储在如下字符串中:20000101 然后您可以使用REGEXP 比较方法以执行所需操作。

    下面的代码使用WP\\u Query元字段生成一个regex,该regex接受年份和日期的任何字符,并匹配特定的月份。

    您需要对您的数据进行此操作,但它看起来是这样的:

    $monthNumber = 6; // e.g. June
    // ensure always two characters, so June will become "06"
    $monthNumberString = str_pad($monthNumber, 2, "0", STR_PAD_LEFT); 
    // regex to only match month
    $matchMonthRegex = \'....\' . $monthNumberString . \'..\'; 
    
    $args = array(
        \'meta_key\' => \'YOUR_BIRTHDAY_META_FIELD_NAME_HERE\',
        \'meta_value\' => $matchMonthRegex,
        \'meta_compare\' => \'REGEXP\'
    );
    
    $result = WP_Query($args);
    
    让我知道这是否有效?

    相关推荐