2014-06-06 78 views
0

我有一個複雜的wp_query正在進行一個新的網站,它返回一些基於日期參數的誤報。WordPress日期查詢返回誤報

我希望用戶能夠根據開始和結束日期搜索事件。每個事件可以有多個「週期」,例如冬季和夏季。

的週期被設置在一個ACF中繼器場,所以在數據庫它看起來像這樣:

時期1:date_0_start-date/date_0_end-date
時期2:date_1_start-date/date_1_end-date
週期3:date_2_start-date/date_2_end-date
etc ...

如果只有一個句點,則查詢可以正常工作。但是,如果有多個時間段,則事件幾乎總是顯示出來,即使它們遠離用戶搜索範圍。

這裏的wp_query:

$args = array( 
    // general 
    'post__in' => $postIDs, 
    'post_type' => 'event', 
    'posts_per_page' => 10, 
    'paged' => $paged, 

    'meta_key' => $_SESSION['search']['sort-key'], 
    'orderby' => $_SESSION['search']['sort-by'], 
    'order' => 'ASC', 

    // category filter 
    'tax_query' => $taxQuery, 

    // date filter 
    'meta_query' => array(
     'relation' => 'AND', 
     array(
      'key' => 'date_%_start-date', 
      'value' => $when, 
      'compare' => '>=', 
      'type' => 'NUMERIC' 
     ), 
     array (
      'key' => 'date_%_end-date', 
      'value' => $when2, 
      'compare' => '<=', 
      'type' => 'NUMERIC' 
     ) 
    ) 


); 

我也被查詢之前添加這些功能稍微改變它允許%查詢是可變的:

function date_to($to) { 
    $to = str_replace("mt1.meta_key = 'date_%_end-date'", "mt1.meta_key LIKE 'date_%_end-date'", $to); 
    return $to; 
} 

function date_from($from) { 
    $from = str_replace("meta_key = 'date_%_start-date'", "meta_key LIKE 'date_%_start-date'", $from); 
    return $from; 
} 

然而,不會檢查%變量是否匹配,因此它可以獲得第1個時間段的開始日期和第2個時間段的結束日期,並使其與用戶查詢匹配。

任何想法,我可以改進這使它更穩健的多個時期?

[編輯] 查詢請求中的評論。

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
FROM wp_posts 
INNER JOIN wp_term_relationships 
ON (wp_posts.ID = wp_term_relationships.object_id) 
INNER JOIN wp_postmeta 
ON (wp_posts.ID = wp_postmeta.post_id) 
INNER JOIN wp_postmeta AS mt1 
ON (wp_posts.ID = mt1.post_id) 
WHERE 1=1 
AND wp_posts.ID 
IN (1033,1039, ... more numbers ... 1264) 
AND (wp_term_relationships.term_taxonomy_id IN (3)) 
AND wp_posts.post_type = 'event' 
AND (wp_posts.post_status = 'publish' 
OR wp_posts.post_status = 'private') 
AND ((wp_postmeta.meta_key LIKE 'date_%_start-date' AND CAST(wp_postmeta.meta_value AS SIGNED) >= '20131201') 
AND (mt1.meta_key LIKE 'date_%_end-date' AND CAST(mt1.meta_value AS SIGNED) <= '20150101')) 
GROUP BY wp_posts.ID 
ORDER BY FIELD(wp_posts.ID, 1033,1039, ... more numbers ... 1264) 
LIMIT 0, 10 

[編輯]

基礎上,下面的答案,還是不太雖然工作更新後的代碼。

新功能:

function add_additional_where_condition($wp_query) { 
    $wp_query = str_replace("WHERE", "WHERE substr(wp_postmeta.meta_key, 1, 6) = substr(mt1.meta_key, 1, 6) AND ", $wp_query); 
    return $wp_query; 
} 

增加是與:
add_filter('posts_where', 'add_additional_where_condition');

SQL返回:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
FROM wp_posts 
INNER JOIN wp_term_relationships 
ON (wp_posts.ID = wp_term_relationships.object_id) 
INNER JOIN wp_postmeta 
ON (wp_posts.ID = wp_postmeta.post_id) 
INNER JOIN wp_postmeta AS mt1 
ON (wp_posts.ID = mt1.post_id) 
INNER JOIN wp_postmeta AS mt2 
ON (wp_posts.ID = mt2.post_id) 
WHERE 1=1 AND wp_posts.ID IN (503,475,529,473,469) 
AND (wp_term_relationships.term_taxonomy_id IN (2)) 
AND wp_posts.post_type = 'event' 
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 
AND (wp_postmeta.meta_key LIKE 'date_%_start-date' 
AND (mt1.meta_key LIKE 'date_%_start-date' AND CAST(mt1.meta_value AS SIGNED) >= '20140611') 
AND (mt2.meta_key LIKE 'date_%_end-date' AND CAST(mt2.meta_value AS SIGNED) <= '20140618')) 
GROUP BY wp_posts.ID 
ORDER BY wp_postmeta.meta_value 
ASC LIMIT 0, 10 
+0

rtm關於'LIKE'模式中的特殊符號。 afaik'_'表示任何符號,所以它必須被轉義'\ _'。附: http://dev.mysql.com/doc/refman/5.6/en/string-comparison-functions.html#operator_like – Deadooshka

+0

嗨,只是嘗試將其更改爲'mt1.meta_key LIKE'date _ \ __ end-date''等。但它沒有返回結果。這是你的建議嗎? – lukeseager

+3

向我們展示數據庫轉儲和真實查詢。 –

回答

1

我覺得你要找的東西不容易實現。

你需要的是這樣的:

AND ((wp_postmeta.meta_key LIKE 'date_%_start-date' AND CAST(wp_postmeta.meta_value AS SIGNED) >= '20131201') 
AND (mt1.meta_key LIKE 'date_%_end-date' AND CAST(mt1.meta_value AS SIGNED) <= '20150101')) 

AND substr(wp_postmeta.meta_key, 1, 6) = substr(mt1.meta_key, 1, 6) 

所以正確的開始日期將用正確的結束日期被使用。

你可以包括一個附加功能,將在WHERE子句的開頭添加此條件:

function add_additional_where_condition($where) { 
    $where .= " AND substr(wp_postmeta.meta_key, 1, 6) = substr(mt1.meta_key, 1, 6) "; 
    return $where; 
} 

兩個substr()應返回相同date_#值。

希望這可以幫助。

+0

嗨,這聽起來像對我來說是正確的一種,但添加函數並沒有真正改變我的任何東西:/它應該改變'WHERE 1 = 1'行嗎? – lukeseager

+0

它不會改變生成的SQL嗎?你是否稱呼這個新功能就像調用'date_to'和'date_from'?改變'1 = 1'會產生同樣的效果,爲了確保查詢的其他部分是相同的,我改變了'WHERE'。 – mucio

+0

不是,由於某種原因完全沒有改變它。是的,我用完全相同的方式調用它,非常奇怪。 – lukeseager

0

您需要meta_query改變type

Documents說: -

type (string) -> Custom field type. 

Possible values are:- 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 
'UNSIGNED'. Default value is 'CHAR'. 

所以嘗試下面的代碼: -

'meta_query' => array(
      'relation' => 'AND', 
      array(
        'key' => 'date_%_start-date', 
        'value' => $when, 
        'compare' => '>=', 
        'type' => 'DATE' 
      ), 
      array (
        'key' => 'date_%_end-date', 
        'value' => $when2, 
        'compare' => '<=', 
        'type' => 'DATE' 
      ) 
    ) 

嘗試根據您的Custom Fild type改變type(eg. Date)

希望這會幫助你。

+0

嗨,剛試過這個,不幸的是沒有工作。我認爲問題更多的是SQL查詢不知道'date_0_start-date'和'date_1_start-date'之間的區別' – lukeseager

+0

你必須指定'key'。或用戶手動查詢。 –

+0

我已經指定了一個密鑰,它在原始帖子中? – lukeseager