使用$ wpdb替代WordPress meta_query

时间:2017-11-21 09:39:42

标签: php mysql wordpress advanced-custom-fields

我正在构建一个基于WordPress的活动网站。每个事件最多需要应用三个日期范围(我已使用Advanced Custom Fields插件添加了这些日期范围)。事件显示在带有日期和类别过滤器的简单页面上。我使用meta_query尝试了这个,但速度非常慢(请参阅下面的代码)。我现在明白这是一个众所周知的问题。所以基本上,我正在寻找替代方案。根据我的阅读,$wpdb是一种可能的解决方案,但我对此没有多少经验。

任何帮助非常感谢。谢谢。

$events = new WP_Query(array(
'post_type' => 'post',
'category_name' => $category_list,
'meta_query' => array(
'relation' => 'OR',

array('relation' => 'AND', array('key' => 'event_start_date_1',  'compare' => '<=', 'value' => $date, 'type' => 'DATE'), array('key' => 'event_finish_date_1', 'compare' => '>=', 'value' => $date, 'type' => 'DATE'),
),

array('relation' => 'AND', array('key' => 'event_start_date_2',  'compare' => '<=', 'value' => $date, 'type' => 'DATE'),array('key' => 'event_finish_date_2', 'compare' => '>=', 'value' => $date, 'type' => 'DATE'),
),

array('relation' => 'AND', array('key' => 'event_start_date_3',  'compare' => '<=', 'value' => $date, 'type' => 'DATE'), array('key' => 'event_finish_date_3', 'compare' => '>=', 'value' => $date, 'type' => 'DATE'),
),

),
));

更新

以下似乎有效

SELECT * FROM $wpdb->posts, $wpdb->postmeta m1, $wpdb->postmeta m2, $wpdb->term_relationships, $wpdb->term_taxonomy, $wpdb->terms

WHERE 

$wpdb->posts.ID = m1.post_id AND $wpdb->posts.ID = m2.post_id 
AND $wpdb->posts.ID = $wpdb->term_relationships.object_id
AND $wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id
AND $wpdb->term_taxonomy.term_id = $wpdb->terms.term_id


AND $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->terms.slug IN ('$category_list')

AND $wpdb->posts.post_status = 'publish'

AND 
(

((m1.meta_key = 'event_start_date_1' AND m1.meta_value <= '$date') AND (m2.meta_key = 'event_finish_date_1' AND m2.meta_value >= '$date'))
OR
((m1.meta_key = 'event_start_date_2' AND m1.meta_value <= '$date') AND (m2.meta_key = 'event_finish_date_2' AND m2.meta_value >= '$date'))
OR
((m1.meta_key = 'event_start_date_3' AND m1.meta_value <= '$date') AND (m2.meta_key = 'event_finish_date_3' AND m2.meta_value >= '$date'))
OR
((m1.meta_key = 'event_start_date_4' AND m1.meta_value <= '$date') AND (m2.meta_key = 'event_finish_date_4' AND m2.meta_value >= '$date'))

)

GROUP BY $wpdb->posts.ID 

我不确定这是最有效的解决方案,因此欢迎任何改进建议。

1 个答案:

答案 0 :(得分:0)

(尝试)希望有所帮助: -

修改where子句以过滤元数据

@Test
public void insertSampleAnalyteLabConfig() throws Exception {
    int newInt = 99;

    SampleAnalyteLabConfig sampleAnalyteLabConfig = createMockSampleAnalyteLabConfig(null);

    when(sampleAnalyteLabConfigService.save(sampleAnalyteLabConfig)).thenAnswer( invocation -> {
        verify(sampleAnalyteLabConfigService, times(1)).save(sampleAnalyteLabConfig);
                SampleAnalyteLabConfig foo = (SampleAnalyteLabConfig) invocation.getArguments()[0];
                foo.setId(newInt);
                return new Long(newInt);
            }
    );

    mockMvc.perform(post("/api/lab/sampleanalytelab")
            .contentType(MediaType.APPLICATION_JSON_UTF8)
            .content(getBytes(sampleAnalyteLabConfig))).andExpect(status().isCreated());
}

将元表加入帖子查询

  add_filter('posts_where', array($this, 'filter_meta_query_where')); 

这是添加元查询的主要功能(我已经为schedules_port添加了条件,您必须自己按照自己的方式构建其余部分): -

add_filter('posts_join' , array($this, 'filter_meta_join'));

以下是联接的代码: -

function filter_meta_query_where($where = '')
{
    global $wpdb; 
    global $wp_query;
    global $sf_form_data;

    if(!is_admin())
    {
        $where .= " AND (($wpdb->postmeta.meta_key = 'schedules_port' AND ($wpdb->postmeta.meta_value LIKE '%$sfrom%' OR $wpdb->postmeta.meta_value LIKE '%$sto%')))";
    }

    return $where;
}