gpt4 book ai didi

wordpress - 使用 meta_query 进行复杂的 custom_field 搜索

转载 作者:行者123 更新时间:2023-12-04 12:45:42 25 4
gpt4 key购买 nike

背景

我正在使用 Advanced Custom Fields Pro 来管理我的自定义字段,它们有一个“repeater”字段,其中包含存储为 repeatername_X_fieldname 的子字段。其中 X 是转发器的行号。

我有一个自定义帖子类型 student其中有中继器 attendance其中包含 dateclass .

因此,当学生上课时,它将按如下方式存储他们的出勤率

  • 元 key :'出勤时间_X_日期'元值 :'20170701'
  • 元 key :'出勤_X_class'元值 :'历史 101'

  • 为了搜索上过某个类(class)或在某个日期范围内参加过的任何学生,我必须上钩 get_meta_sql并转换我的 meta_query使用 LIKE而不是 =当值包含 %
    function key_rewrite($parts){
    foreach($parts as &$part){
    $part = preg_replace("/(meta_key = )(\'[^']*[%][^']*\')/", "meta_key LIKE $2", $part);
    }
    return $parts;
    }
    add_action( 'get_meta_sql', 'key_rewrite');

    这让我可以做类似的事情
    $args = array(
    'post_type' => 'student',
    'meta_query' => array(
    array(
    'key'=>'attendance_%_class',
    'compare'=>'=',
    'value'=>'History 101'
    )
    )
    );
    $my_query = new WP_Query($args);

    为了搜索任何参加过历史 101 或
    $args = array(
    'post_type' => 'student',
    'meta_query' => array(
    array(
    'key'=>'attendance_%_date',
    'compare'=>'>=',
    'value'=>'20170101'
    )
    )
    );

    寻找今年参加过的任何人。

    问题第 1 部分

    我需要能够搜索今年参加过“历史 101”的任何人。

    最初,meta_query 上的简单 AND 似乎可以解决问题:
    $args = array(
    'post_type' => 'student',
    'meta_query' => array(
    'relation' => 'AND',
    array(
    'key'=>'attendance_%_class',
    'compare'=>'=',
    'value'=>'History 101'
    ),
    array(
    'key'=>'attendance_%_date',
    'compare'=>'>=',
    'value'=>'20170101'
    )
    )
    );

    然而,由于通配符没有关联,这实际上可以返回去年参加“历史 101”的人,但今年却是不同的类(class)。

    问题第 2 部分

    我实际上需要能够获得今年参加过“历史 101”但在过去一周内根本没有出现在类里面的每个人的名单。这使问题进一步复杂化,因为我需要结合 meta_query 的 EXISTSNOT EXISTS有一个附加条件。同样,从表面上看,使用嵌套的 meta_queries 这听起来相当简单:
    $args = array(
    'post_type' => 'student',
    'meta_query' => array(
    'relation' => 'AND',
    array(
    'relation' => 'AND',
    array(
    //Just assume by some magic we resolved Problem part 1
    'key'=>'attendance_%_class',
    'compare'=>'=',
    'value'=>'History 101'
    ),
    array(
    'key'=>'attendance_%_date',
    'compare'=>'>=',
    'value'=>'20170101'
    )
    ),
    array(
    'relation' => 'AND',
    array(
    //again... magic!
    'key'=>'attendance_%_class',
    'compare'=>'=',
    'value'=>'History 101'
    ),
    array(
    'key'=>'attendance_%_date',
    'compare'=>'>',
    'value'=>'20170821'
    ),
    array(
    'key'=>'attendance_%_date',
    'compare'=>'NOT EXISTS'
    )
    )
    )
    );

    显然,这是由逻辑问题造成的,但令人印象深刻的是,WordPress 通过在元查询中每次使用一次加入 postmeta 表来解决其中的大部分问题。不幸的是,这意味着在 NOT EXISTS 中没有使用 > 日期部分。 ON因而不能使用 IS NULL测试它不存在。

    我知道这非常复杂,如果你跟着我,我会印象深刻。如果没有,请提出问题,以便我帮助澄清。

    是的,我知道我可以完全编写自己的查询,但我试图坚持使用内置的 WordPress 工具。

    帮助!

    最佳答案

    我一直在那里......试图将所有内容都放在一个复杂的元查询中。最后需要手动处理生成的SQL——移动括号、替换运算符、引号等。

    最后,查询非常复杂,并且有多个连接到 postmeta 的连接。表变得太昂贵和缓慢。

    我选择通过选择稍微不同的方法来实现这一点。
    因此,您可以做的是将查询拆分为多个子查询,然后将它们与 post__in 合并。和 post__not_in ,

    例如 问题第 1 部分 :

    /* Filter by class */
    $history_students_ids = get_posts(array(
    'post_type' => 'student',
    'fields' => 'ids',
    'posts_per_page' => -1,
    'meta_query' => array(
    array(
    'key'=>'attendance_%_class',
    'compare'=>'=',
    'value'=>'History 101'
    ),
    )
    ));

    /* Filter by date */
    $students = get_posts(array(
    'post_type' => 'student',
    'post__in' => $history_students_ids,
    'meta_query' => array(
    array(
    'key'=>'attendance_%_date',
    'compare'=>'>=',
    'value'=>'20170101'
    )
    )
    ));

    也是如此问题第 2 部分
    $not_attended_history_students_ids = get_posts(array(
    'post_type' => 'student',
    'post__in' => $history_students_ids,
    'fields' => 'ids',
    'posts_per_page' => -1,
    'meta_query' => array(
    array(
    'key'=>'attendance_%_date',
    'compare'=>'NOT EXISTS'
    )
    )
    ));

    $students = get_posts(array(
    'post_type' => 'student',
    'post__in' => $not_attended_history_students_ids,
    'meta_query' => array(
    array(
    'key'=>'attendance_%_date',
    'compare'=>'>=',
    'value'=>'20170101'
    )
    )
    ));

    您可以将出勤条件反转为 EXISTS 并使用 post__not_in ...我希望你已经理解了这个想法。

    关于wordpress - 使用 meta_query 进行复杂的 custom_field 搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45928591/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com