प्रति श्रेणी के सीमित पदों के साथ कई श्रेणियों के लिए WP_Query का उपयोग करना?


10

मेरे पास प्रत्येक 15 पोस्ट के साथ 3 श्रेणियां हैं, मैं चाहता हूं कि प्रत्येक श्रेणी के लिए केवल 5 पहली पोस्ट लाने वाले db को एक क्वेरी दी जाए, मैं यह कैसे कर सकता हूं?

$q = new WP_Query(array( 'post__in' => array(2,4,8), 'posts_per_page' => **FIRST_5_OF_EACH_CAT** ));

यदि यह संभव नहीं है, तो अधिक कुशल क्या है, मूल श्रेणी के लिए सभी पोस्ट प्राप्त करना और उनके माध्यम से लूप करना या 3 अलग-अलग प्रश्न बनाना है?


आप उन्हें कैसे ऑर्डर करना चाहते हैं?
माइकस्किंकल

हाल ही में प्रकाशित किया गया है .. इसलिए श्रेणी ए के सबसे हाल के 5, श्रेणी बी के सबसे हाल के सामान ..
अमित

ठीक है, मेरा जवाब नीचे देखें
माइकस्किंकल

जवाबों:


16

आप जो चाहते हैं वह संभव है लेकिन आपको एसक्यूएल में तल्लीन करने की आवश्यकता होगी जिसे मैं जब भी संभव हो बचना पसंद करता हूं (क्योंकि मुझे पता नहीं है, मैं एक अग्रिम एसक्यूएल डेवलपर हूं, लेकिन क्योंकि वर्डप्रेस में आप जब भी संभव हो एपीआई का उपयोग करना चाहते हैं भविष्य की संभावित डेटाबेस संरचना परिवर्तनों से संबंधित भविष्य की संगतता समस्याओं को कम करने के लिए।)

UNIONसंचालक के साथ SQL एक संभावना है

एसक्यूएल का उपयोग करने के लिए आपको UNIONअपनी क्वेरी में एक ऑपरेटर की आवश्यकता होती है , ऐसा कुछ आपकी श्रेणी के स्लग हैं "category-1", "category-1"और "category-3":

SELECT * FROM wp_posts WHERE ID IN (
  SELECT tr.object_id
  FROM wp_terms t 
  INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
  INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
  WHERE tt.taxonomy='category' AND t.slug='category-1'
  LIMIT 5

  UNION

  SELECT tr.object_id
  FROM wp_terms t 
  INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
  INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
  WHERE tt.taxonomy='category' AND t.slug='category-2'
  LIMIT 5

  UNION

  SELECT tr.object_id
  FROM wp_terms t 
  INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
  INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
  WHERE tt.taxonomy='category' AND t.slug='category-3'
  LIMIT 5
)

आप posts_joinफ़िल्टर के साथ SQL UNION का उपयोग कर सकते हैं

उपरोक्त का उपयोग करके आप या तो सीधे कॉल कर सकते हैंposts_join या आप निम्नानुसार एक फिल्टर हुक का उपयोग कर सकते हैं ; ध्यान दें कि मैं PHP heredoc का उपयोग कर रहा हूँ, इसलिए सुनिश्चित करें SQL;कि फ्लश बचे हुए हैं। यह भी ध्यान दें कि मैंने एक सरणी में श्रेणी के स्लग को सूचीबद्ध करके आपको हुक के बाहर की श्रेणियों को परिभाषित करने की अनुमति देने के लिए एक वैश्विक संस्करण का उपयोग किया। आप इस कोड को एक प्लगइन या अपनी थीम की functions.phpफ़ाइल में रख सकते हैं :

<?php
global $top_5_for_each_category_join;
$top_5_for_each_category_join = array('category-1','category-2','category-3');
add_filter('posts_join','top_5_for_each_category_join',10,2);
function top_5_for_each_category_join($join,$query) {
  global $top_5_for_each_category_join;
  $unioned_selects = array();
  foreach($top_5_for_each_category_join as $category) {
    $unioned_selects[] =<<<SQL
SELECT object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='{$category}'
LIMIT 5
SQL;
  }
  $unioned_selects = implode("\n\nUNION\n\n",$unioned_selects);
  return $join . " INNER JOIN ($unioned_selects) categories ON wp_posts.ID=categories.object_id " ;
}

लेकिन इसके साइड-इफेक्ट्स हो सकते हैं

निश्चित रूप से क्वेरी संशोधन हुक का उपयोग करना जैसे posts_joinहमेशा साइड-इफेक्ट्स को आमंत्रित करता है, जिसमें वे प्रश्नों पर विश्व स्तर पर कार्य करते हैं और इस प्रकार आपको आमतौर पर अपने संशोधनों को लपेटने की आवश्यकता होती है, ifजिसमें केवल इसका उपयोग किया जाता है जब जरूरत होती है और परीक्षण के लिए कौन से मापदंड मुश्किल हो सकते हैं।

इसके बजाय अनुकूलन पर ध्यान दें?

हालाँकि, मुझे लगता है कि आपका सवाल चिंतित है अनुकूलन के बारे में अधिक से अधिक एक शीर्ष 5 समय 3 क्वेरी करने में सक्षम होने के बारे में है, है ना? अगर ऐसा है तो शायद दूसरे विकल्प हैं जो वर्डप्रेस एपीआई का उपयोग करते हैं?

कैशिंग के लिए ट्रांजिस्टर एपीआई का उपयोग करना बेहतर है?

मुझे लगता है कि आपकी पोस्ट अक्सर, सही नहीं बदलेगी? क्या होगा यदि आप समय-समय पर तीन (3) क्वेरी को स्वीकार करते हैं और फिर ट्रांज़िशन एपीआई का उपयोग करके परिणामों को कैश करते हैं ? आपको बनाए रखने योग्य कोड और शानदार प्रदर्शन मिलेगा; UNIONऊपर क्वेरी से बेहतर एक अच्छा है क्योंकि वर्डप्रेस wp_optionsतालिका के एक रिकॉर्ड में क्रमबद्ध सरणी के रूप में पदों की सूचियों को संग्रहीत करेगा ।

आप निम्न उदाहरण ले सकते हैं और test.phpइसे जांचने के लिए अपनी वेब साइट की जड़ में छोड़ सकते हैं :

<?php

$timeout = 4; // 4 hours
$categories = array('category-1','category-2','category-3');

include "wp-load.php";
$category_posts = get_transient('top5_posts_per_category');
if (!is_array($category_posts) || count($category_posts)==0) {
  echo "Hello Every {$timeout} hours!";
  $category_posts = array();
  foreach($categories as $category) {
    $posts = get_posts("post_type=post&numberposts=5&taxonomy=category&term={$category}");
    foreach($posts as $post) {
      $category_posts[$post->ID] = $post;
    }
  }
  set_transient('top5_posts_per_category',$category_posts,60*60*$timeout);
}
header('Content-Type:text/plain');
print_r($category_posts);

सारांश

हाँ, जबकि आप SQL UNIONक्वेरी और posts_joinफ़िल्टर हुक का उपयोग करने के लिए आपसे पूछ सकते हैं कि आप शायद ट्रांसजेंडर एपीआई के बजाय कैशिंग का उपयोग कर बेहतर पेशकश कर रहे हैं ।

उम्मीद है की यह मदद करेगा?


2
साइट पर प्रभाव को कम करने के लिए ग्राहकों के माध्यम से कैशिंग एक अच्छी बात है।
hakre

1
@ ग्राहकों का उपयोग करने पर बहुत अच्छा विचार है।
क्रिस_ओ

@ मायके, अगर मैं आपके महाद्वीप में रह रहा होता तो मैं आपके साथ कक्षाएं लेता! एक बार फिर धन्यवाद!
अमित

@ नमस्कार: LOL! :-)
माइकस्किंकेल

1
क्या आप क्षणिक रूप से भी अनिश्चित काल के लिए बचा सकते हैं और फिर इसे save_post पर फ्लश कर सकते हैं? कोडेक्स में एक अच्छा उदाहरण (edit_term हुक का उपयोग करके) है
हेलगेटहाइकिंग

1

WP_Query()प्रत्येक बिल्ली के लिए फर्स्ट एक्स जैसी किसी चीज का समर्थन नहीं करता है । इसके बजाय WP_Query()आप अपनी get_posts()प्रत्येक श्रेणी पर उपयोग कर सकते हैं , इसलिए तीन बार कहें:

<?php
$posts      = array():
$categories = array(2,4,8);
foreach($categories as $cat) {
  $posts[] = get_posts('numberposts=5&offset=1&category='.$cat);
}
?>

$posts अब प्रत्येक श्रेणी के लिए पहले पाँच पोस्ट शामिल हैं।


नहीं है कि 3 DB को हिट? मैं जानना चाहता था कि क्या आप इसे 1 हिट में कर सकते हैं क्योंकि मुझे लगा कि यह अधिक कुशल है।
अमित

अच्छी तरह से है कि क्या DB के लिए है, है ना? इससे डेटा क्वेरी करें। db ऐसे सामान के लिए बना है। यह संभवत: तेज है और आप जो जटिल सीक्वल क्वेरी पूछ रहे हैं उसे चलाना। सामान का उपयोग करने से डरो मत। यदि यह आपकी साइट को तोड़ता है, तो इसे यहां रिपोर्ट करें।
हकर्रे

mm .. मिल गया, मुझे php / mysql / db दक्षता के बारे में ज्यादा जानकारी नहीं है (और अधिक पढ़ना चाहते हैं), यकीन है कि कम हिट बेहतर थी और फिर परिणाम खुद को पार्स करें।
अमित

1
अच्छी तरह से, सच है, आम तौर पर अधिक है और कम से कम है। लेकिन पहले परखें और परखें। आपका सॉफ्टवेयर जितना खराब है, अनुकूलन के लिए उतनी ही अधिक क्षमता है। इसलिए बेहतर करना सीखें, क्योंकि अंत में आप तेजी से बेहतर सॉफ्टवेयर लिखेंगे और बेहतर सॉफ्टवेयर लिखेंगे।
21

0

मुझे एक क्वेरी में प्रत्येक श्रेणी के लिए पहले पाँच पद प्राप्त करने का तरीका नहीं पता है। यदि आप कभी भी केवल 45 पदों पर जा रहे हैं, तो एक बार डेटाबेस को मारना और प्रत्येक श्रेणी के लिए अपने पांच पद प्राप्त करना संभवतः सबसे कुशल दृष्टिकोण है। डेटाबेस को तीन बार मारना और परिणामों को संयोजित करना हालांकि एक बुरी बात नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.