প্রশ্নটিতে কাস্টম টেবিল অন্তর্ভুক্ত করতে কীভাবে WP_Query প্রসারিত করবেন?


31

আমি এখন এই ইস্যুটি নিয়ে দিন কাটিয়েছি। প্রাথমিকভাবে এটি ছিল, কীভাবে কোনও ব্যবহারকারীর অনুগামী ডেটা ডাটাবেসে সংরক্ষণ করবেন, যার জন্য আমি এখানে ওয়ার্ডপ্রেস উত্তরগুলিতে বেশ কয়েকটি সুপারিশ পেয়েছি। এর পরে, সুপারিশগুলি অনুসরণ করে আমি এর মতো একটি নতুন টেবিল যুক্ত করেছি:

id  leader_id   follower_id
1   2           4
2   3           10
3   2           10

উপরের সারণীতে, প্রথম সারিতে 2 টি আইডি সহ একটি ব্যবহারকারী রয়েছে যাকে অনুসরণকারী 4 আইডি ব্যবহার করে থাকে দ্বিতীয় দ্বিতীয় সারিতে 3 আইডি সহ একটি ব্যবহারকারী একটি আইডি সহ একটি ব্যবহারকারী অনুসরণ করছেন 10. একই যুক্তি তৃতীয় সারির জন্য প্রযোজ্য।

এখন, মূলত আমি WP_Query প্রসারিত করতে চাই যাতে আমি কেবল একটি ব্যবহারকারীর নেতা (গুলি) দ্বারা প্রাপ্ত পোস্টগুলিতে সীমাবদ্ধ রাখতে পারি। সুতরাং, উপরের টেবিলটি বিবেচনায় রেখে, যদি আমি ব্যবহারকারীর আইডি 10 ডাব্লুপি_কিউয়েরিতে পাস করি তবে ফলাফলগুলিতে কেবল ব্যবহারকারী আইডি 2 এবং ব্যবহারকারী আইডি 3 এর পোস্ট থাকতে হবে।

আমি উত্তর খুঁজতে চেষ্টা করে অনেক অনুসন্ধান করেছি। বা না, আমি কীভাবে ডব্লিউপি_কিউয়ারি ক্লাসটি বাড়িয়ে তুলতে পারি তা বুঝতে সহায়তা করার জন্য কোনও টিউটোরিয়াল দেখেছি। আমি মাইক শিনকেলের উত্তরগুলি একই ধরণের প্রশ্নের (WP_Query প্রসারিত) দেখেছি, তবে কীভাবে এটি আমার প্রয়োজনীয়তার সাথে প্রয়োগ করতে হয় তা আমি সত্যিই বুঝতে পারি নি। কেউ যদি আমাকে এটির জন্য সাহায্য করতে পারে তবে দুর্দান্ত হবে।

মাইকের উত্তরের অনুরোধ হিসাবে লিঙ্কগুলি: লিঙ্ক 1 , লিঙ্ক 2


মাইকের উত্তরগুলিতে একটি লিঙ্ক যুক্ত করুন, দয়া করে।
কায়সার

1
আপনি কী জিজ্ঞাসা করছেন তার একটি উদাহরণ দিতে পারেন? WP_Queryপোস্ট পাওয়ার জন্য, এবং এই পোস্টগুলির সাথে কীভাবে সম্পর্ক রয়েছে তা বুঝতে আমি ব্যর্থ হয়েছি।
mor7ifer

@ কাইজার আমি মাইকের উত্তরের লিঙ্কগুলি সহ প্রশ্নটি আপডেট করেছি।
জন

@ m0r7if3r »আমি ডব্লিউপি_কিউয়ারিকে প্রসারিত করতে চাই যাতে আমি কেবল একটি ব্যবহারকারীর নেতার ()) দ্বারা প্রাপ্ত পোস্টগুলিতে সীমাবদ্ধ রাখতে পারি, সুতরাং" লেখকের পোস্ট পেতে "এর অনুরূপ।
কায়সার

2
@ m0r7if3r পোস্টগুলি হ'ল আমাকে যা জিজ্ঞাসা করতে হবে তা হ'ল। তবে আনতে হবে এমন পোস্টগুলি কাস্টম টেবিলের নির্দিষ্ট ব্যবহারকারীর নেতা হিসাবে তালিকাভুক্ত ব্যবহারকারীদের হওয়া উচিত। সুতরাং, অন্য কথায় আমি ডব্লিউপি_কিউয়ারিকে বলতে চাই, কাস্টম টেবিলটিতে আইডি '10' থাকা একজন ব্যবহারকারী হিসাবে তালিকাভুক্ত সমস্ত ব্যবহারকারীদের সমস্ত পোস্ট আনুন।
জন

উত্তর:


13

গুরুত্বপূর্ণ অস্বীকৃতি: এটি করার সঠিক উপায়টি আপনার টেবিলের কাঠামোটি সংশোধন করা নয়, তবে wp_usermeta ব্যবহার করা। তারপরে আপনার পোস্টগুলি জিজ্ঞাসা করার জন্য আপনার কোনও কাস্টম এসকিউএল তৈরি করার প্রয়োজন হবে না (যদিও উদাহরণস্বরূপ, প্রশাসনের বিভাগে, বিশেষ তত্ত্বাবধায়কের প্রতিবেদন করা প্রত্যেকের একটি তালিকা পেতে আপনার কিছু কাস্টম এসকিউএল প্রয়োজন হবে)। যাইহোক, ওপি কাস্টম এসকিউএল লেখার বিষয়ে জিজ্ঞাসা করেছিল, তাই বিদ্যমান ওয়ার্ডপ্রেস ক্যোয়ারিতে কাস্টম এসকিউএল ইনজেকশন দেওয়ার জন্য বর্তমান সেরা অনুশীলন।

যদি আপনি জটিল যোগদান করে থাকেন তবে আপনি কেবল পোস্ট_এই ফিল্টার ব্যবহার করতে পারবেন না, কারণ আপনার যোগদানের ক্ষেত্রে, নির্বাচনটি এবং সম্ভবত কোয়েরির অংশগুলি অনুসারে গোষ্ঠী বা ক্রমটি সংশোধন করতে হবে।

আপনার সেরা বাজি 'পোস্ট_ক্লাউস' ফিল্টার ব্যবহার করা। এটি একটি অত্যন্ত কার্যকর ফিল্টার (এটির অপব্যবহার করা উচিত নয়!) যা আপনাকে এসকিউএলের বিভিন্ন অংশ সংযোজন / সংশোধন করতে দেয় যা ওয়ার্ডপ্রেস কোরের মধ্যে অনেকগুলি লাইনের কোডের দ্বারা স্বয়ংক্রিয়ভাবে উত্পন্ন হয়। ফিল্টার কলব্যাক স্বাক্ষর: function posts_clauses_filter_cb( $clauses, $query_object ){ }এবং এটি প্রত্যাশা করে আপনি ফিরে আসবেন $clauses

ক্লজ

$clausesনিম্নলিখিত একটি কী রয়েছে এমন একটি অ্যারে; প্রতিটি কী একটি এসকিউএল স্ট্রিং যা ডাটাবেসে প্রেরিত চূড়ান্ত এসকিউএল বিবৃতিতে সরাসরি ব্যবহৃত হবে:

  • কোথায়
  • groupby
  • যোগদানের
  • orderby
  • স্বতন্ত্র
  • ক্ষেত্র
  • সীমা

আপনি যদি ডাটাবেসে একটি সারণী যুক্ত করে থাকেন (কেবলমাত্র আপনি যদি পোস্ট_মেটা, ব্যবহারকারী_মেটা বা কর আদায় করতে না পারেন তবে এটি করুন) আপনাকে সম্ভবত এই ধারাগুলির একটিরও বেশি স্পর্শ করতে হবে, উদাহরণস্বরূপ, fields"" নির্বাচন করুন " এসকিউএল স্টেটমেন্টের অংশ), join(আপনার "FROM" ধারাটিতে থাকা আপনার সমস্ত টেবিল) এবং সম্ভবত orderby

ধারাগুলি সংশোধন করা হচ্ছে

এটি করার সর্বোত্তম উপায় হ'ল আপনি $clausesফিল্টার থেকে পাওয়া অ্যারে থেকে প্রাসঙ্গিক কীটিকে সাব্র্যাক্ট করে তুলুন :

$join = &$clauses['join'];

এখন, আপনি যদি সংশোধন করেন $join, আপনি আসলে সরাসরি সংশোধন করবেন $clauses['join']তাই আপনি $clausesযখন এটি ফিরিয়ে দেবেন তখন পরিবর্তনগুলি আসবে ।

অরিজিনাল ক্লজগুলি সংরক্ষণ করা

সম্ভাবনাগুলি (না, গুরুত্ব সহকারে শুনুন) আপনি বিদ্যমান এসকিউএল সংরক্ষণ করতে চাইবেন যা ওয়ার্ডপ্রেস আপনার জন্য তৈরি করেছে generated যদি তা না হয় তবে এর posts_requestপরিবর্তে আপনার ফিল্টারটি সম্ভবত দেখা উচিত - এটি সম্পূর্ণ মাইএসকিউএল কোয়েরি হ'ল এটি ডেটাবেজে প্রেরণের ঠিক আগে, যাতে আপনি এটি নিজের নিজের সাথে পুরোপুরি ক্লোবার করতে পারেন। তুমি কেন এটা করতে চাও? আপনি সম্ভবত না।

সুতরাং, ধারাগুলিতে বিদ্যমান এসকিউএল সংরক্ষণের জন্য, অনুচ্ছেদগুলিতে সংযোজন করা মনে রাখবেন, তাদেরকে অর্পণ করবেন না (যেমন: ব্যবহার করবেন $join .= ' {NEW SQL STUFF}';না $join = '{CLOBBER SQL STUFF}';Note মনে রাখবেন যে $clausesঅ্যারের প্রতিটি উপাদান একটি স্ট্রিং, যদি আপনি এটিতে যুক্ত করতে চান, অন্য কোনও অক্ষর টোকেনের আগে আপনি সম্ভবত একটি স্থান সন্নিবেশ করতে চাইবেন, অন্যথায় আপনি সম্ভবত কিছু এসকিউএল সিন্ট্যাক্স ত্রুটি তৈরি করবেন।

আপনি অনুমান করতে পারেন যে প্রতিটি অনুচ্ছেদে সর্বদা কিছু না কিছু থাকবে এবং তাই প্রতিটি নতুন স্ট্রিং একটি স্থান দিয়ে শুরু করে মনে রাখবেন যেমন:: $join .= ' my_table, বা আপনি সর্বদা একটি সামান্য রেখা যুক্ত করতে পারেন যা আপনার প্রয়োজন হলে কেবল একটি স্থান যুক্ত করে:

$join = &$clauses['join'];
if (! empty( $join ) ) $join .= ' ';
$join .= "JOIN my_table... "; // <-- note the space at the end
$join .= "JOIN my_other_table... ";


return $clauses;

এটি অন্য যে কোনও কিছুর চেয়ে স্টাইলিস্টিক জিনিস। গুরুত্বপূর্ণ বিটটি মনে রাখতে হবে: আপনার স্ট্রিংয়ের আগে সর্বদা একটি স্থান ছেড়ে যান যদি আপনি এমন কোনও ধারাটিতে যুক্ত হন যা ইতিমধ্যে এতে কিছু এসকিউএল রয়েছে!

একসাথে রেখে

ওয়ার্ডপ্রেস বিকাশের প্রথম নিয়মটি হ'ল যথাসম্ভব মূল কার্যকারিতাটি ব্যবহার করার চেষ্টা করা। এটি আপনার কাজের ভবিষ্যতের প্রমাণের সর্বোত্তম উপায়। ধরুন মূল দলটি সিদ্ধান্ত নিয়েছে যে ওয়ার্ডপ্রেস এখন এসকিউএলাইট বা ওরাকল বা অন্য কোনও ডাটাবেস ভাষা ব্যবহার করবে। কোনও হাতে লেখা মাইএসকিউএল অবৈধ হয়ে যেতে পারে এবং আপনার প্লাগইন বা থিমটি ভেঙে দিতে পারে! ডাব্লুপি নিজে থেকে যথাসম্ভব এসকিউএল উত্পন্ন করতে দেওয়া এবং আপনার প্রয়োজনীয় বিটগুলি যুক্ত করা আরও ভাল।

সুতরাং ব্যবসায়ের প্রথম ক্রম WP_Queryআপনার বেস ক্যোয়ারির যথাসম্ভব উত্পন্ন করার জন্য উপকৃত হচ্ছে । সঠিক পদ্ধতি আমরা এই কাজ করতে ব্যবহার করেন তার উপর মূলত নির্ভর করে যেখানে পোস্টের এই তালিকা প্রদর্শিত অনুমিত হয়। যদি এটি পৃষ্ঠার একটি উপ-বিভাগ (আপনার মূল ক্যোয়ারী নয়) আপনি ব্যবহার করবেন get_posts(); যদি এটি মূল জিজ্ঞাসা হয় তবে আমি মনে করি আপনি এটি ব্যবহার করতে query_posts()এবং এটি দিয়ে কাজটি করতে পারতেন তবে এটি করার সঠিক উপায়টি হ'ল মূল ক্যোয়ারীটি ডাটাবেসকে হিট করার আগে (এবং সার্ভার চক্র গ্রহণ করে) তাই requestফিল্টারটি ব্যবহার করুন ।

ঠিক আছে, সুতরাং আপনি আপনার ক্যোয়ারী তৈরি করেছেন এবং এসকিউএল তৈরি হতে চলেছে। ঠিক আছে, আসলে এটি তৈরি করা হয়েছে, কেবল ডাটাবেসে প্রেরণ করা হয়নি। posts_clausesফিল্টারটি ব্যবহার করে , আপনি আপনার কর্মচারী সম্পর্কের টেবিলটি মিশ্রণে যুক্ত করতে যাচ্ছেন। আসুন এই টেবিলটিকে {$ wpdb-> উপসর্গ call বলুন} 'ব্যবহারকারী_ সম্পর্কিততা', এবং এটি একটি ছেদ টেবিল। (যাইহোক, আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি এই টেবিলের কাঠামোটি সাধারণীকরণ করুন এবং নীচের ক্ষেত্রগুলি সহ এটি একটি যথাযথ ছেদযুক্ত টেবিলে পরিণত করুন: 'সম্পর্ক_আইডি', 'ব্যবহারকারী_আইডি', 'সম্পর্কিত_ ব্যবহারকারী_আইডি', 'সম্পর্ক_প্রকার'; এটি অনেক বেশি নমনীয় এবং শক্তিশালী)। .. কিন্তু আমার দ্বিমত আছে).

আপনি যদি কী করতে চান তা যদি আমি বুঝতে পারি তবে আপনি কোনও নেতার আইডি পাস করতে চান এবং তারপরে সেই নেতার অনুসারীদের কেবল পোস্টগুলি দেখতে পাবেন। আমি আশা করি আমি অধিকার পেয়েছি। যদি এটি সঠিক না হয় তবে আপনাকে যা বলি তা গ্রহণ করতে হবে এবং এটি আপনার প্রয়োজনের সাথে খাপ খাইয়ে নিতে হবে। আমি আপনার টেবিলের কাঠামোর সাথে লেগে থাকব: আমাদের একটি leader_idএবং একটি রয়েছে follower_id। সুতরাং {$wpdb->posts}.post_authorজয়ন আপনার 'ব্যবহারকারীর_সম্পর্ক' টেবিলে 'অনুসরণকারী_আইডি'-এর একটি বিদেশী কী হিসাবে চালু থাকবে ।

add_filter( 'posts_clauses', 'filter_by_leader_id', 10, 2 ); // we need the 2 because we want to get all the arguments

function filter_by_leader_id( $clauses, $query_object ){
  // I don't know how you intend to pass the leader_id, so let's just assume it's a global
  global $leader_id;

  // In this example I only want to affect a query on the home page.
  // This is where the $query_object is used, to help us avoid affecting
  // ALL queries (since ALL queries pass through this filter)
  if ( $query_object->is_home() ){
    // Now, let's add your table into the SQL
    $join = &$clauses['join'];
    if (! empty( $join ) ) $join .= ' '; // add a space only if we have to (for bonus marks!)
    $join .= "JOIN {$wpdb->prefix}employee_relationship EMP_R ON EMP_R.follower_id = {$wpdb->posts}.author_id";

    // And make sure we add it to our selection criteria
    $where = &$clauses['where'];
    // Regardless, you always start with AND, because there's always a '1=1' statement as the first statement of the WHERE clause that's added in by WP/
    // Just don't forget the leading space!
    $where .= " AND EMP_R.leader_id={$leader_id}"; // assuming $leader_id is always (int)

    // And I assume you'll want the posts "grouped" by user id, so let's modify the groupby clause
    $groupby = &$clauses['groupby'];
    // We need to prepend, so...
    if (! empty( $groupby ) ) $groupby = ' ' . $groupby; // For the show-offs
    $groupby = "{$wpdb->posts}.post_author" . $groupby;
  }

  // Regardless, we need to return our clauses...
  return $clauses;
}

13

আমি অত্যন্ত দেরিতে এই প্রশ্নের উত্তর দিচ্ছি এবং এর জন্য আমার ক্ষমাও চাই। আমি এতে যোগদানের সময়সীমা নিয়ে খুব ব্যস্ত হয়ে পড়েছিলাম।

আমি আমার অ্যাপ্লিকেশনটিতে প্রসারিত এবং প্রয়োগ করতে পারি এমন বেস সমাধানগুলি সরবরাহ করতে @ m0r7if3r এবং @ কাইজারকে একটি বড় ধন্যবাদ এই উত্তরটি @ m0r7if3r এবং @ কাইজার দ্বারা প্রদত্ত সমাধানগুলির আমার অভিযোজন সম্পর্কে বিশদ সরবরাহ করে।

প্রথমে আমাকে এই প্রশ্নটি কেন প্রথম স্থানে জিজ্ঞাসা করা হয়েছিল তা ব্যাখ্যা করতে দিন। প্রশ্ন এবং এর মন্তব্যগুলি থেকে কেউ একত্রিত হতে পারে যে আমি প্রদত্ত ব্যবহারকারী (অনুসারী) অনুসরণকারী সমস্ত ব্যবহারকারী (নেতা) দ্বারা পোস্টগুলি টানতে ডব্লিউপি_কিউয়ারি পাওয়ার চেষ্টা করছি। অনুসারী এবং নেতার মধ্যে সম্পর্ক একটি কাস্টম টেবিলে সঞ্চিত follow। এই সমস্যার সর্বাধিক সাধারণ সমাধান হ'ল অনুসরণকারী সারণী থেকে অনুসরণকারী সমস্ত নেতাদের ব্যবহারকারীর আইডি টানুন এবং এটিকে একটি অ্যারেতে রাখুন। নিচে দেখ:

global $wpdb;
$results = $wpdb->get_results($wpdb->prepare('SELECT leader_id FROM cs_follow WHERE follower_id = %s', $user_id));

foreach($results as $result)
    $leaders[] = $result->leader_id;

একবার আপনার নেতাদের অ্যারে হয়ে গেলে আপনি এটিকে WP_Query এর পক্ষে যুক্তি হিসাবে পাস করতে পারেন। নিচে দেখ:

if (isset($leaders)) $authors = implode(',', $leaders); // Necessary as authors argument of WP_Query only accepts string containing post author ID's seperated by commas

$args = array(
    'post_type'         => 'post',
    'posts_per_page'    => 10,
    'author'            => $authors
);

$wp_query = new WP_Query( $args );

// Normal WordPress loop continues

উপরের সমাধানটি আমার কাঙ্ক্ষিত ফলাফল অর্জনের সহজতম উপায়। তবে এটি স্কেলেবল নয়। দশকের দশকে অনুসরণকারী এবং হাজার হাজার নেতাদের অনুসরণকারী এই মুহুর্তে লিডার আইডির ফলস্বরূপ অ্যারে অত্যন্ত বড় হয়ে উঠবে এবং আপনার ওয়ার্ডপ্রেস সাইটকে প্রতিটি পৃষ্ঠার লোডে 100 এমবি - 250 এমবি মেমরি ব্যবহার করতে বাধ্য করবে এবং অবশেষে সাইটটি ক্রাশ করবে। সমস্যার সমাধান হ'ল সরাসরি ডাটাবেসে এসকিউএল কোয়েরি চালানো এবং প্রাসঙ্গিক পোস্টগুলি আনা। @ M0r7if3r এর সমাধান যখন উদ্ধার করতে এসেছিল তখনই। @ কায়সারের সুপারিশ অনুসরণ করে আমি উভয় বাস্তবায়ন পরীক্ষা করার জন্য বেরিয়েছি। আমি ওয়ার্ডপ্রেসের একটি নতুন পরীক্ষা ইনস্টলটিতে নিবন্ধভুক্ত করতে একটি সিএসভি ফাইল থেকে প্রায় 47K ব্যবহারকারী আমদানি করেছি। ইনস্টলটি কুড়ি ইলেভেন থিমটি চলছিল। এটি অনুসরণ করে আমি প্রায় 50 জন ব্যবহারকারীকে অন্য প্রতিটি ব্যবহারকারীর অনুসরণ করতে লুপের জন্য দৌড়েছিলাম। @ কেজার এবং @ এম0r7if3r এর সমাধান উভয়ের জন্য ক্যোয়ারী সময়ের মধ্যে পার্থক্য বিস্ময়কর ছিল। @ কায়সার এর সমাধান প্রতিটি প্রশ্নের জন্য সাধারণত 2 থেকে 5 সেকেন্ড সময় নেয়। ওয়ার্ডপ্রেস পরবর্তী ব্যবহারের জন্য ক্যোয়ারীগুলি ক্যাচ করার সাথে সাথে আমার ধারণাটির বিভিন্নতা ঘটে। অন্যদিকে @ m0r7if3r এর সমাধানে গড়ে 0.02 এমএসের ক্যোয়ারী সময় প্রদর্শিত হয়েছে। উভয় সমাধানের পরীক্ষার জন্য আমার কাছে লিডার_আইডি কলামের জন্য সূচি চালু ছিল। ইনডেক্স না করে ক্যোয়ারির সময় নাটকীয়ভাবে বৃদ্ধি পেয়েছিল।

অ্যারে ভিত্তিক সমাধান ব্যবহার করার সময় মেমরির ব্যবহারটি 100-150 এমবি প্রায় দাঁড়িয়েছিল এবং সরাসরি এসকিউএল চালানোর সময় 20 এমবিতে নেমে যায়।

যখন আমাকে পোস্ট_এই ফিল্টার ফাংশনে ফলোয়ার আইডিটি পাস করার দরকার হয় তখন আমি @ m0r7if3r এর সমাধান দিয়ে একটি দ্বিধায় আঘাত করি। অন্ততপক্ষে, আমার জ্ঞান অনুযায়ী ওয়ার্ডপ্রেস ফাইলার ফাংশনে কোনও ভেরিয়েবল পাস করার কোনও মাধ্যমকে অনুমতি দেয় না। আপনি যদিও গ্লোবাল ভেরিয়েবল ব্যবহার করতে পারেন তবে আমি গ্লোবালগুলি এড়াতে চেয়েছিলাম। শেষ পর্যন্ত সমস্যাটি সমাধান করার জন্য আমি WP_Query প্রসারিত করে শেষ করেছি। সুতরাং আমি চূড়ান্ত সমাধানটি এখানে প্রয়োগ করেছি (@ m0r7if3r এর সমাধানের উপর ভিত্তি করে)।

class WP_Query_Posts_by_Leader extends WP_Query {
    var $follower_id;

    function __construct($args=array()) {
        if(!empty($args['follower_id'])) {
            $this->follower_id = $args['follower_id'];
            add_filter('posts_where', array($this, 'posts_where'));
        }

        parent::query($args);
    }

    function posts_where($where) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'follow';
        $where .= $wpdb->prepare(" AND post_author IN (SELECT leader_id FROM " . $table_name . " WHERE follower_id = %d )", $this->follower_id);
        return $where;
    }
}


$args = array(
    'post_type'         => 'post',
    'posts_per_page'    => 10,
    'follower_id'       => $follower_id
);

$wp_query = new WP_Query_Posts_by_Leader( $args );

দ্রষ্টব্য: আমি অবশেষে নিম্নলিখিত সারণীতে 1.2 মিলিয়ন এন্ট্রি সহ উপরের সমাধানটি চেষ্টা করেছি। গড় ক্যোয়ারির সময়টি 0.060 এমএসের কাছাকাছি দাঁড়িয়েছিল।


3
আমি আপনাকে কখনই বলিনি যে আমি এই প্রশ্নে আলোচনার কতটা প্রশংসা করেছি। এখন যখন আমি জানতে পেরেছি যে আমি এটি মিস করেছি, আমি একটি উত্সাহ যোগ করেছি :)
কায়সার

8

আপনি posts_whereফিল্টারটি ব্যবহার করে সম্পূর্ণ এসকিউএল সমাধান দিয়ে এটি করতে পারেন । এখানে এর একটি উদাহরণ:

if( some condition ) 
    add_filter( 'posts_where', 'wpse50305_leader_where' );
    // lol, question id is the same forward and backward

function wpse50305_leader_where( $where ) {
    $where .= $GLOBALS['wpdb']->prepare( ' AND post_author '.
        'IN ( '.
            'SELECT leader_id '.
            'FROM custom_table_name '.
            'WHERE follower_id = %s'.
        ' ) ', $follower_id );
    return $where;
}

আমি মনে করি JOINএটির সাথেও করার উপায় আছে তবে আমি এটি নিয়ে আসতে পারি না। আমি এটি নিয়ে খেলতে থাকব এবং যদি উত্তরটি পাই তবে তা আপডেট করব।

পর্যায়ক্রমে, @ কাইজারের পরামর্শ অনুসারে, আপনি এটিকে দুটি ভাগে ভাগ করতে পারেন: নেতাদের পাওয়া এবং কোয়েরি করা। আমার মনে হচ্ছে এটি কম দক্ষ হতে পারে তবে এটি আরও বোধগম্য উপায়। নেস্টেড এসকিউএল অনুসন্ধানগুলি বেশ ধীর হয়ে যেতে পারে বলে কোন পদ্ধতিটি ভাল তা নির্ধারণ করার জন্য আপনাকে নিজের জন্য দক্ষতা পরীক্ষা করতে হবে।

মন্তব্যগুলি থেকে:

আপনার ফাংশনটি আপনার মধ্যে রাখা উচিত functions.phpএবং পদ্ধতিটি add_filter()বলার আগে সঠিকভাবে করা উচিত । অবিলম্বে এটি অনুসরণ করে, আপনার উচিত যাতে এটি অন্যান্য প্রশ্নের উপর প্রভাব না ফেলে।query()WP_Queryremove_filter()


1
আপনার এ সম্পাদনা করে যুক্ত করা হয়েছে prepare()। আশা করি আপনি সম্পাদনাটি মনে করবেন না। এবং হ্যাঁ: কর্মক্ষমতা রয়েছে ওপি দ্বারা পরিমাপ করা হয়। যাইহোক: আমি এখনও মনে করি এটি কেবল ইউজারমেটা হওয়া উচিত এবং অন্য কিছু নয়।
কায়সার

একটি সমাধান চেষ্টা করার জন্য @ m0r7if3r Thx। আমি সম্ভাব্য স্কেলিবিলিটি সমস্যা নিয়ে উদ্বেগ সহ কায়সারের উত্তরের উত্তরে একটি মন্তব্য পোস্ট করেছি। এটি বিবেচনায় নিতে দয়া করে।
জন

1
@ কাইজার কিছু মনে করবেন না, আসলে আমি বরং এটি প্রশংসা করি :)
মরিফায়ার

@ m0r7if3r ধন্যবাদ সম্প্রদায়ের
শৈলীতে

1
আপনার ফাংশনটি আপনার মধ্যে রাখা উচিত functions.phpএবং পদ্ধতিটি add_filter()বলার আগে সঠিকভাবে করা উচিত । অবিলম্বে এটি অনুসরণ করে, আপনার উচিত যাতে এটি অন্যান্য প্রশ্নের উপর প্রভাব না ফেলে। আমি নিশ্চিত নই যে ইউআরএল পুনর্লিখনের সমস্যাটি কী হবে, আমি অনেক সময় ব্যবহার করেছি এবং এটি কখনও দেখিনি ...query()WP_Queryremove_filter()posts_where
mor7ifer

6

টেমপ্লেট ট্যাগ

আপনার functions.phpফাইলে উভয় ফাংশন রাখুন । তারপরে 1 ম ফাংশনটি সামঞ্জস্য করুন এবং আপনার কাস্টম সারণির নাম যুক্ত করুন। তারপরে ফলস্বর অ্যারের ভিতরে থাকা বর্তমান ব্যবহারকারী আইডি থেকে মুক্তি পেতে আপনার কিছু চেষ্টা / ত্রুটি হওয়া দরকার (মন্তব্য দেখুন)।

/**
 * Get "Leaders" of the current user
 * @param int $user_id The current users ID
 * @return array $query The leaders
 */
function wpse50305_get_leaders( $user_id )
{
    global $wpdb;

    return $wpdb->query( $wpdb->prepare(
        "
            SELECT `leader_id`, `follower_id`
            FROM %s
                WHERE `follower_id` = %s
            ORDERBY `leader_id` ASC
        ",
        // Edit the table name
        "{$wpdb->prefix}custom_table_name"
        $user_id
    ) );
}

/**
 * Get posts array that contain posts by 
 * "Leaders" the current user is following
 * @return array $posts Posts that are by the current "Leader
 */
function wpse50305_list_posts_by_leader()
{
    get_currentuserinfo();
    global $current_user;

    $user_id = $current_user->ID;

    $leaders = wpse5035_get_leaders( $user_id );
    // could be that you need to loop over the $leaders
    // and get rid of the follower ids

    return get_posts( array(
        'author' => implode( ",", $leaders )
    ) );
}

টেম্পলেট ভিতরে

এখানে আপনি নিজের ফলাফলগুলি দিয়ে যা কিছু করতে পারেন তা করতে পারেন।

foreach ( wpse50305_list_posts_by_leader() as $post )
{
    // do something with $post
}

উল্লেখ্য আমরা চি testdata আছে, ইত্যাদি তাই উপরে একটি অনিশ্চয়তার খেলা একটি সামান্য বিট হয়। নিশ্চিত হয়ে নিন যে আপনি এই উত্তরটি আপনার পক্ষে কী কাজ করেছে তার সাথে সম্পাদনা করেছেন, তাই পরবর্তী পাঠকদের জন্য আমাদের একটি সন্তোষজনক ফলাফল রয়েছে। আপনার খুব কম খ্যাতি পাওয়া গেলে আমি সম্পাদনাটি অনুমোদন করব। তারপরে আপনি এই নোটটিও মুছতে পারেন। ধন্যবাদ।


2
JOINহয় আরো অনেক কিছু ব্যয়বহুল। প্লাস: যেমনটি আমি উল্লেখ করেছি, আমাদের কাছে পরীক্ষার ডেটা নেই, সুতরাং দয়া করে উভয় উত্তর পরীক্ষা করে নিন এবং আপনার ফলাফল সহ আমাদের আলোকিত করুন।
কায়সার

1
অনুসন্ধানের সময় ডাব্লুপিউকিউয়ারি নিজেই পোস্ট টেবিল এবং পোস্টমেটার মধ্যে জোয়েন্টগুলির সাথে কাজ করে। আমি পিএইচপি মেমরির ব্যবহারের প্রতিচ্ছবি 70 এমবি - 200 এমবি প্রতি পৃষ্ঠার লোডে দেখেছি। অনেক যুগপত ব্যবহারকারীর সাথে এরকম কিছু চালানোর জন্য চূড়ান্ত অবকাঠামোগত প্রয়োজন। আমার ধারণাটি হ'ল যেহেতু ওয়ার্ডপ্রেস ইতিমধ্যে অনুরূপ কৌশল প্রয়োগ করে, তাই যুক্তদের আইডির অ্যারের সাথে কাজ করার তুলনায় কম কর দেওয়া উচিত।
জন

1
@ জন শুনতে ভাল লাগছে। সত্যিই আসন্ন জানতে চাই।
কায়সার

4
ঠিক আছে এখানে পরীক্ষার ফলাফল। এর জন্য আমি একটি সিএসভি ফাইল থেকে প্রায় 47 কে ব্যবহারকারী যুক্ত করেছি। পরে, প্রথম 45 জন ব্যবহারকারীকে অন্য প্রতিটি ব্যবহারকারীকে অনুসরণ করতে লুপের জন্য দৌড়ে যান। এর ফলে আমার কাস্টম টেবিলটিতে 3,704,951 টি রেকর্ড সংরক্ষিত হয়েছে। প্রাথমিকভাবে, @ m0r7if3r এর সমাধানটি আমাকে 95 সেকেন্ডের ক্যোয়ারির সময় দিয়েছে, যা নেদার_আইডি কলামে সূচি চালু করার পরে 0.020 এমএসে চলে গেছে। মোট পিএইচপি মেমরি গ্রাহক হয়েছিল প্রায় 20MB। অন্যদিকে, আপনার সমাধানটি সূচীকরণ অন দিয়ে প্রশ্নের জন্য প্রায় 2 থেকে 5 সেকেন্ড সময় নিয়েছিল। মোট পিএইচপি মেমরি গ্রাস করা হয়েছে প্রায় 117MB।
জন

1
মন্তব্যে কোড ফরম্যাটিংটি কেবল
সাফল্য

3

দ্রষ্টব্য: এই উত্তরটি মন্তব্যগুলিতে বর্ধিত আলোচনা এড়ানোর জন্য

  1. পরীক্ষার ব্যবহারকারীদের প্রথম সেট যুক্ত করার জন্য, মন্তব্যগুলি থেকে ওপিএস কোডটি এখানে। আমি একটি বাস্তব বিশ্বের উদাহরণে পরিবর্তন করতে হবে।

    for ( $j = 2; $j <= 52; $j++ ) 
    {
        for ( $i = ($j + 1); $i <= 47000; $i++ )
        {
            $rows_affected = $wpdb->insert( $table_name, array( 'leader_id' => $i, 'follower_id' => $j ) );
        }
    }

    পরীক্ষার বিষয়ে ওপি এর জন্য আমি একটি সিএসভি ফাইল থেকে প্রায় 47 কে ব্যবহারকারী যুক্ত করেছি। পরে, প্রথম 45 জন ব্যবহারকারীকে অন্য প্রতিটি ব্যবহারকারীকে অনুসরণ করতে লুপের জন্য দৌড়ে যান।

    • এর ফলে আমার কাস্টম টেবিলটিতে 3,704,951 টি রেকর্ড সংরক্ষিত হয়েছে।
    • প্রাথমিকভাবে, @ m0r7if3r এর সমাধানটি আমাকে 95 সেকেন্ডের ক্যোয়ারির সময় দিয়েছে, যা নেদার_আইডি কলামে সূচি চালু করার পরে 0.020 এমএসে চলে গেছে। মোট পিএইচপি মেমরি গ্রাহক হয়েছিল প্রায় 20MB।
    • অন্যদিকে, আপনার সমাধানটি সূচীকরণ অন দিয়ে প্রশ্নের জন্য প্রায় 2 থেকে 5 সেকেন্ড সময় নিয়েছিল। মোট পিএইচপি মেমরি গ্রাস করা হয়েছে প্রায় 117MB।
  2. এই পরীক্ষার আমার উত্তর:

    আরও একটি "বাস্তব জীবন" পরীক্ষা: প্রতিটি ব্যবহারকারীর একটি অনুসরণ $leader_amount = rand( 0, 5 );করুন এবং তারপরে $leader_amount x $random_ids = rand( 0, 47000 );প্রতিটি ব্যবহারকারীর সংখ্যা যুক্ত করুন । এতক্ষণ আমরা যা জানি তা হ'ল: যদি কোনও ব্যবহারকারী একে অপর ব্যবহারকারীকে অনুসরণ করে তবে আমার সমাধান চূড়ান্তভাবে খারাপ হবে। আরও: আপনি কীভাবে পরীক্ষাটি করেছেন এবং কোথায় টাইমার যুক্ত করেছেন ঠিক তা আপনি প্রদর্শন করবেন।

    আমাকে আরও উল্লেখ করতে হবে যে - উপরের সময় ট্র্যাকিংটি সত্যই পরিমাপ করা যায় না, কারণ এটি লুপকে একসাথে গণনা করতে সময় নিতে পারে। দ্বিতীয় লুপের ফলাফলের আইডি সেট করে লুপ করা ভাল।

এখানে আরও প্রক্রিয়া


2
যারা এই প্রশ্নটি অনুসরণ করে চলেছেন তাদের জন্য দ্রষ্টব্য: আমি বিভিন্ন অবস্থার অধীনে পারফরম্যান্স পরিমাপের প্রক্রিয়াধীন এবং ফলাফলটি এক বা একদিনে পোস্ট করব This পরীক্ষার তথ্যগুলির স্কেলের কারণে এটি অত্যন্ত সময়সাপেক্ষ কাজ হয়ে দাঁড়িয়েছে যা হওয়া দরকার উত্পন্ন।
জন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.