অর্ডারবাই মেটা_ভ্যালু কেবলমাত্র মেটা_কি বিদ্যমান পোস্টগুলি প্রদান করে


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 ফলাফল কারণ এখানে কেবলমাত্র 10 টি newsপোস্ট রয়েছে meta_key = custom_author_name। তবে এমন শত শত newsপোস্ট রয়েছে যে নির্দিষ্ট মেটা_কি দিয়ে পোস্ট_মেটা সারি নেই। দয়া করে লক্ষ্য করুন, এতে কোনও মেটা_কিউরি জড়িত নেই। কোনও মেটা_ভ্যালু বরাদ্দ করা হয়নি, কারণ আমি কেবল মেটা_কি পোস্টগুলি বাছাই করার চেষ্টা করছি এবং মেটা_ভ্যালু দ্বারা ফিল্টার করছি না।

অর্ডারবাই সব পোস্ট নির্বাচন করা উচিত নয়? এবং শুধু তাদের আদেশ?

যদি তাই হয় তবে ফলাফল ফিল্টার করা হয় কেন? যদি মেটা_কি না পাওয়া যায় তবে কেন কেবল খালি স্ট্রিং বা সমস্ত মিল না ব্যবহার করবেন?

তা না হলে কেন?

আমি যদি প্রতিটি নিউজ পোস্টে মেটা_কি প্রবেশ করি (এটি একটি খালি স্ট্রিং হলেও) তবে আমি প্রত্যাশিত ফলাফলটি পেয়েছি। তবে এটি পুরো টেবিল সারিগুলির মতো মনে হয় যা সেখানে থাকার দরকার নেই।

উত্তর:


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'এটি ক্রম পরিবর্তন করে, তবে আসল মেটা ক্ষেত্রের সাথে এর কোনও যোগসূত্র ছিল না।
জেক 11

3

আমি @Manny Fleurmond এর উত্তর প্রয়োগের চেষ্টা এবং @Jake আমি টাইপো যে সংশোধন করার পরেও কাজ বুঝে উঠতে পারতাম না 'orderby' => 'meta_key'হওয়া উচিত 'orderby' => 'meta_value'। (এবং সম্পূর্ণতার জন্য এটি হওয়া উচিত 'posts_per_page'নয় 'post_per_page'তবে এটি যে বিষয়টি দেখেছে তাতে প্রভাব ফেলবে না))

আপনি যদি @ ম্যানি ফ্লেয়ারমন্ডের উত্তর (টাইপস সংশোধন করে) দ্বারা উত্পন্ন এসকিউএল ক্যোয়ারীটি লক্ষ্য করেন তবে এটিই আপনি পাবেন:

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

এটি ডাব্লুপি কীভাবে কোয়েরি ওয়ার্সকে পার্স করছে তা চিত্রিত করে: এটি প্রতিটি মেটা_কিউরি ক্লোজের জন্য একটি টেবিল তৈরি করছে, তারপরে কীভাবে যুক্ত হবে এবং কী অর্ডার করবেন তা নির্ধারণ করুন। অর্ডারিং ঠিকঠাক কাজ করবে যদি আপনি কেবলমাত্র একটি একক ধারা ব্যবহার করে থাকেন 'compare' => 'EXISTS'তবে 'compare' => 'NOT EXISTS'ওআর (যেমন আমাদের অবশ্যই) দিয়ে দ্বিতীয় ধারাটিতে যোগ দিলে ক্রমটি অর্জিত হয়। ফলাফলটি হচ্ছে প্রথম বাম / টেবিল এবং দ্বিতীয় ধারা / টেবিল উভয়কে যোগ দিতে বাম জয়েন্ট ব্যবহার করা হয় - এবং ডাব্লুপি যেভাবে সমস্ত কিছু একসাথে রাখে তার অর্থ হ'ল যে টেবিলটি তৈরি করে 'compare' => 'EXISTS'তা আসলে কোনও কাস্টম ক্ষেত্র থেকে মেটা_ভ্যালুতে পপুলেটেড হয় না 'custom_author_name'ক্ষেত্রটি আমরা আগ্রহী So সুতরাং আমি মনে করি cla ধারা / সারণি অনুসারে অর্ডার করলে কেবলমাত্র 'নিউজ'-এর নির্দিষ্ট পোস্ট_প্রকারের একটিমাত্র কাস্টম ক্ষেত্র থাকলে পছন্দসই ফলাফল পাওয়া যাবে।

আমার পরিস্থিতির জন্য যে সমাধানটি কাজ করেছিল তা হ'ল অন্য ধারা / সারণি দ্বারা অর্ডার করা - এটির অস্তিত্ব নেই। আপাতদৃষ্টিতে পাল্টা স্বজ্ঞাত আমি জানি, তবে ডাব্লুপি কোয়েরি ওয়ার্সকে যেভাবে পার্স করেছে তা এই টেবিলটি যেখানে 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

আমি যা কিছু করেছি তা হ'ল কলামগুলি দেখানো হচ্ছে এবং দফা দ্বারা গ্রুপ অপসারণ করা হয়েছে। এটি তখন আমাকে কী ঘটছে তা দেখিয়েছিল - যে postmeta.meta_value কলামটি সমস্ত মেটা_কিগুলি থেকে মানগুলি টানছিল, যখন 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তবে স্ট্রিংগুলির জন্য আলাদা পদ্ধতির প্রয়োজন হবে।
ডিজেবি

1

বাস্তবে এটি কীভাবে কাজ করে।

আপনি যদি টেবিল সারি যুক্ত না করে এটি করতে চান তবে আপনাকে দুটি প্রশ্ন করতে হবে। মেটা_কি সহ একটি যার সীমিত ফলাফল রয়েছে এবং অন্যটি সম্পূর্ণ তালিকা পেয়েছে; তারপরে দুটি ক্যোয়ারী ফলাফলের তুলনা করার জন্য পিএইচপি ব্যবহার করুন (সম্ভবত নকলগুলি সরিয়ে দিতে অন্য কোয়েরি থেকে মেটা_কি ফলাফলগুলি সরিয়ে ফেলতে বা আপনার সেটিংয়ে যা কিছু বোঝার আছে)


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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.