ऑर्डरबी मेटाएवल्यू केवल उन्हीं पदों को लौटाता है जिनमें मौजूदा मेटा_की है


10

मेरे पास निम्नलिखित wp_query है:

$args = array(
    'post_type' => 'news',
    'orderby' => 'meta_key',
    'order' => 'ASC',
    'meta_key'=>'custom_author_name',
    'post_per_page'=>-1
);

$query = new WP_Query($args);

echo $query->found_posts;

इको = 10 परिणाम क्योंकि newsए के साथ केवल 10 पद हैं meta_key = custom_author_name। लेकिन सैकड़ों newsपोस्ट हैं जिनके पास उस विशिष्ट मेटा_की के साथ पोस्ट_मेटा पंक्ति नहीं है। कृपया ध्यान दें, इसमें कोई मेटा_क्वरी शामिल नहीं है। कोई मेटा_वल्यू असाइन नहीं किया गया है, क्योंकि मैं केवल मेटा_की द्वारा पोस्ट्स को सॉर्ट करने की कोशिश कर रहा हूं, और मेटावॉल्यू द्वारा फ़िल्टर नहीं।

क्या सभी पदों का चयन नहीं करना चाहिए? और बस उन्हें आदेश?

यदि ऐसा है तो परिणाम क्यों फ़िल्टर किया जाता है? यदि meta_key नहीं मिला है, तो बस एक खाली स्ट्रिंग, या सभी मैच का उपयोग क्यों न करें?

यदि नहीं, तो क्यों नहीं?

अगर मैं प्रत्येक समाचार पोस्ट पर एक मेटा_की दर्ज करता हूं (भले ही यह एक खाली स्ट्रिंग है) तो मुझे अपेक्षित परिणाम मिलता है। लेकिन ऐसा लगता है कि तालिका पंक्तियों की एक पूरी बहुत कुछ है कि वहाँ होने की जरूरत नहीं है।

जवाबों:


10

जैसा कि @ एम्ब्रोसिया के जवाब में कहा गया है, इसके जैसा काम करना चाहिए। एक बार जब आप एक मेटा क्वेरी की घोषणा करते हैं, भले ही आप एक विशिष्ट मूल्य की तलाश न कर रहे हों, यह केवल उस मेटा कुंजी के साथ पोस्ट की गई क्वेरी को घोषित करेगा। यदि आप सभी पोस्ट को मेटा कुंजी द्वारा क्रमबद्ध करना चाहते हैं, तो निम्न कोड का उपयोग करें:

$args = array(
    'post_type' => 'news',
    'orderby' => 'meta_value',
    'order' => 'ASC',
    'meta_query' => array(
        'relation' => 'OR',
        array( 
            'key'=>'custom_author_name',
            'compare' => 'EXISTS'           
        ),
        array( 
            'key'=>'custom_author_name',
            'compare' => 'NOT EXISTS'           
        )
    ),
    'posts_per_page'=>-1
);

$query = new WP_Query($args);

echo $query->found_posts;

यह क्या करता है एक उन्नत मेटा क्वेरी का उपयोग करें जो उन पोस्टों के लिए दिखता है जो करते हैं और उस मेटा कुंजी को घोषित नहीं करते हैं। चूँकि EXISTSआप पहले वाले हैं, जब आप meta_valueइसे क्रमबद्ध करते हैं , तो यह पहली क्वेरी का उपयोग करेगा।


3
इसने मेरे लिए ऑर्डर बिल्कुल नहीं बदला, जब मैंने उपयोग किया 'orderby' => 'meta_value', तो इसने ऑर्डर को बदल दिया, लेकिन इसका वास्तविक मेट्रो क्षेत्र से कोई लेना-देना नहीं था।
जेक

3

मैंने @ मैननी फ्लेममंड के उत्तर को लागू करने की कोशिश की और @ जेक की तरह मुझे वह टाइपो को ठीक करने के बाद भी काम करने के लिए नहीं मिला जो 'orderby' => 'meta_key'होना चाहिए 'orderby' => 'meta_value'। (और पूर्णता के लिए यह 'posts_per_page'नहीं होना चाहिए 'post_per_page'लेकिन इस मुद्दे को देखा जा रहा है प्रभावित नहीं करता है।)

यदि आप SQL क्वेरी को वास्तव में @Manny Fleurmond के जवाब (टाइपो को सही करते हुए) द्वारा उत्पन्न करते हैं, तो यह वही है जो आप देखते हैं:

SELECT   wp_{prefix}_posts.* FROM wp_{prefix}_posts
LEFT JOIN wp_{prefix}_postmeta ON (wp_{prefix}_posts.ID = wp_{prefix}_postmeta.post_id AND wp_{prefix}_postmeta.meta_key = 'custom_author_name' )
LEFT JOIN wp_{prefix}_postmeta AS mt1 ON ( wp_{prefix}_posts.ID = mt1.post_id )
WHERE 1=1  AND ( 
    wp_{prefix}_postmeta.post_id IS NULL 
    OR 
    mt1.meta_key = 'custom_author_name'
) AND wp_{prefix}_posts.post_type = 'news' AND
(wp_{prefix}_posts.post_status = 'publish' OR wp_{prefix}_posts.post_author = 1 AND wp_{prefix}_posts.post_status = 'private')
GROUP BY wp_{prefix}_posts.ID ORDER BY wp_{prefix}_postmeta.meta_value ASC

यह दिखाता है कि WP क्वेरी क्वेरी को पार्स कर रहा है जिस तरह से: यह प्रत्येक मेटा_क्वारी क्लॉज के लिए एक तालिका बना रहा है, फिर यह पता लगाना है कि उन्हें कैसे शामिल किया जाए और क्या ऑर्डर किया जाए। यदि आप केवल एक ही क्लॉज़ का उपयोग कर रहे हैं, तो आदेश ठीक काम करेगा 'compare' => 'EXISTS', लेकिन 'compare' => 'NOT EXISTS'(जैसा कि हमें करना होगा) के साथ दूसरे क्लॉज़ को जोड़ने से ऑर्डर गड़बड़ हो जाता है। इसका परिणाम यह है कि LEFT JOIN का उपयोग पहले क्लॉज़ / टेबल और दूसरे क्लॉज़ / टेबल दोनों में शामिल होने के लिए किया जाता है - और जिस तरह से WP सब कुछ एक साथ रखता है, इसका मतलब है कि उपयोग 'compare' => 'EXISTS'की गई तालिका वास्तव में किसी भी कस्टम फ़ील्ड से meta_values ​​से पॉप्युलेट की जा रही है, न कि सिर्फ 'custom_author_name'जिस क्षेत्र में हम रुचि रखते हैं। इसलिए मुझे लगता है कि उस खंड / तालिका द्वारा आदेश देने से केवल वांछित परिणाम मिलेंगे यदि 'समाचार' के विशेष पोस्ट_टाइप में केवल एक ही कस्टम फ़ील्ड है।

मेरी स्थिति के लिए काम करने वाले समाधान को अन्य खंड / तालिका द्वारा ऑर्डर करना था - NOT EXISTS एक। मुझे पता है कि प्रति-सहजता से पता चलता है, लेकिन जिस तरह से WP क्वेरी चर को पार्स करता है, वह यह तालिका है जहां meta_valueकेवल कस्टम फ़ील्ड के बाद ही हम पॉपुलेटेड होते हैं।

(मेरे द्वारा इस मामले के लिए इस क्वेरी के समतुल्य चलाने का एकमात्र तरीका यह है:

SELECT   wp_{prefix}_posts.ID, wp_{prefix}_postmeta.meta_value, mt1.meta_value FROM wp_{prefix}_posts
LEFT JOIN wp_{prefix}_postmeta ON (wp_{prefix}_posts.ID = wp_{prefix}_postmeta.post_id AND wp_{prefix}_postmeta.meta_key = 'custom_author_name' )
LEFT JOIN wp_{prefix}_postmeta AS mt1 ON ( wp_{prefix}_posts.ID = mt1.post_id )
WHERE 1=1  AND ( 
    wp_{prefix}_postmeta.post_id IS NULL 
    OR 
    mt1.meta_key = 'custom_author_name'
) AND wp_{prefix}_posts.post_type = 'news' AND
(wp_{prefix}_posts.post_status = 'publish' OR wp_{prefix}_posts.post_author = 1 AND wp_{prefix}_posts.post_status = 'private')
ORDER BY wp_{prefix}_postmeta.meta_value ASC

मैंने जो कुछ किया है वह कॉलम दिखाया जा रहा है और ग्रुप बाय क्लॉज को हटा दिया गया है। इसके बाद मुझे पता चला कि क्या चल रहा था - कि पोस्टमेटा.मेटा_वेल्यू कॉलम सभी मेटा_की से मानों में खींच रहा था, जबकि mt1.meta_value कॉलम समाचार कस्टम फ़ील्ड से केवल मेटा_वल्यूज़ में खींच रहा था।)

समाधान

जैसा कि @ मैन्नी फ्लेमर्ड कहते हैं, यह पहला क्लॉज है जो ऑर्डरबी के लिए उपयोग किया जाता है, इसलिए इसका उत्तर केवल क्लॉस राउंड को स्वैप करना है, यह दे:

$args = array(
    'post_type' => 'news',
    'orderby' => 'meta_value',
    'order' => 'ASC',
    'meta_query' => array(
        'relation' => 'OR',
        array( 
            'key' => 'custom_author_name',
            'compare' => 'NOT EXISTS'           
        ),
        array( 
            'key' => 'custom_author_name',
            'compare' => 'EXISTS'           
        )
    ),
    'posts_per_page' => -1
);

$query = new WP_Query($args);

वैकल्पिक रूप से आप क्लॉस साहचर्य सरणियों और इसी कुंजी द्वारा आदेश कर सकते हैं, जैसे:

$args = array(
    'post_type' => 'news',
    'orderby' => 'not_exists_clause',
    'order' => 'ASC',
    'meta_query' => array(
        'relation' => 'OR',
        'exists_clause' => array( 
            'key' => 'custom_author_name',
            'compare' => 'EXISTS'           
        ),
        'not_exists_clause' => array( 
            'key' => 'custom_author_name',
            'compare' => 'NOT EXISTS'           
        )
    ),
    'posts_per_page' => -1
);

$query = new WP_Query($args);

यह इंगित करने के लायक है कि यदि मेटा कुंजी custom_author_nameसेट है और फिर परेशान है, तो meta_keyवह प्रतिक्रिया देगा EXISTSऔर इसका प्रभाव यह होगा कि उन पोस्टों के साथ बबल्ड किया जाएगा जिनके पास ए है custom_author_name। मेरे मामले में मेरे पास एक चेकबॉक्स है, इसलिए मैं "value" => "1"इसके बजाय उपयोग कर रहा हूं EXISTS, लेकिन स्ट्रिंग्स को एक अलग दृष्टिकोण की आवश्यकता होगी।
djb

1

यह वास्तव में यह कैसे काम करता है।

यदि आप तालिका पंक्तियों को जोड़े बिना ऐसा करना चाहते हैं, तो आपको दो प्रश्न करने होंगे। एक मेटा_की के साथ जिसके सीमित परिणाम हैं, और दूसरा जो पूरी सूची प्राप्त करता है; फिर दो क्वेरी परिणामों की तुलना करने के लिए PHP का उपयोग करें (संभवतः डुप्लिकेट को निकालने के लिए अन्य क्वेरी से मेटा_की परिणाम को हटाकर, या आपकी सेटिंग में जो कुछ भी समझ में आता है)।


0

दुर्भाग्य से, यह नहीं है कि कैसे WP_Queryकाम करता है। जैसे ही आप उस "मेटा" घटक को जोड़ते हैं, आपने एक प्रकार का फ़िल्टर बनाया है। डंप $query->requestऔर आप देखेंगे कि मेरा क्या मतलब है।

दूसरा, WP_Queryमेटा कुंजी द्वारा ऑर्डर करने का समर्थन बिल्कुल नहीं करता है । आप किसी विशेष कुंजी के लिए मेटा मान द्वारा ऑर्डर कर सकते हैं लेकिन कुंजी द्वारा ही नहीं। फिर से, क्वेरी को देखने के लिए कि मेरा क्या मतलब है। आप देखेंगे कि यदि आप कोशिश करते हैं तो "ऑर्डर" घटक बाहर निकल जाते हैं।

मेरी राय में, इसे प्राप्त करने का सबसे साफ तरीका, छोटे फिल्टर की एक जोड़ी है:

function join_meta_wpse_188287($join) {
  remove_filter('posts_join','join_meta_wpse_188287');
  global $wpdb;
  return ' INNER JOIN '.$wpdb->postmeta.' ON ('.$wpdb->posts.'.ID = '.$wpdb->postmeta.'.post_id)';
}
add_filter('posts_join','join_meta_wpse_188287');

function orderby_meta_wpse_188287($orderby) {
  remove_filter('posts_orderby','orderby_meta_wpse_188287');
  global $wpdb;
  return $wpdb->postmeta.'.meta_key ASC';
}
add_filter('posts_orderby','orderby_meta_wpse_188287');

$args = array(
    'post_type' => 'news',
    'post_per_page'=>-1
);
$q = new WP_Query($args);
var_dump($q->request); // debug
var_dump(wp_list_pluck($q->posts,'post_title')); // debug
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.