ค้นหาโพสต์ทั้งหมดที่ไม่มีเมตาคีย์


50

ฉันพยายามรับคิวรีเพื่อดึงโพสต์ทั้งหมดที่meta_keyไม่มีอยู่และสร้างมันขึ้นมา

ฉันมีปัญหาในการค้นหาโพสต์เหล่านั้นเนื่องจากแบบสอบถามที่ฉันทดสอบไม่ทำงาน

นี่คือรหัสที่ฉันใช้เพื่อพยายามรับโพสต์เหล่านั้น:

$args = array(
   'posts_per_page' => 18,
   'cat'=>1955,
   'post_status'=>'publish',
   'meta_query' => array(
                  array(
                     'key' => 'colors',
                     'compare' => 'NOT EXISTS'
                  ),
   ));      

query_posts($args);

สิ่งนี้จะส่งคืนอะไรหากไม่มีโพสต์ที่มีคีย์colorsแต่ส่งคืนidsโพสต์ด้วยคีย์colorsเมื่อใดก็ตามที่มีคีย์นั้น (ตรงข้ามกับที่ฉันต้องการ) ฉันลองEXISTแทน แต่ไม่มีโชค

หากใครบางคนสามารถให้คำแนะนำฉันเกี่ยวกับวิธีการสร้างแบบสอบถามอย่างถูกต้องเช่นเดียวกับที่ฉันต้องการฉันจะขอบคุณมัน

ขอบคุณ!


คุณใช้เวิร์ดเพรสรุ่นใด
s_ha_dum

สวัสดีขอโทษสำหรับการละเว้น ฉันใช้ v3.5
JordanBel

ดูเหมือนว่ามีการเพิ่มประเภทของข้อความค้นหา (ด้วยการเปรียบเทียบชุดเป็นไม่อยู่) ใน 3.5 ดังนั้นจึงควรทำงานตามที่เป็นอยู่เท่าที่ฉันเห็น มันจะเป็นเรื่องง่ายที่จะทำมันผ่านแบบสอบถาม SELECT ที่กำหนดเอง แต่ ...
โทมัส Buteler

ขอบคุณฉันจะลองใช้ select ฉันต้องเรียนรู้ก่อนว่าจะใช้ตารางใดในการสืบค้นและจะทำตามคำถามได้อย่างไร :(
JordanBel

ที่แปลกมาก. ฉันไม่เห็นปัญหากับรหัสนั้นและคุณใช้ 3.5+ ซึ่งเป็นสาเหตุที่ฉันถาม คุณได้ตรวจสอบฐานข้อมูลเพื่อยืนยันว่าข้อมูลของคุณถูกแทรกในแบบที่คุณคิดหรือไม่
s_ha_dum

คำตอบ:


73

ฉันทำการทดสอบเพิ่มเติมกับสิ่งนี้และไม่สามารถหาเหตุผลได้ว่าจะไม่ทำงาน (ยกเว้นรหัสข้างต้นเป็นเพียงตัวอย่างข้อมูลและรหัสจริงที่ตรงกับตัวอย่างของฉันด้านล่าง) อย่างไรก็ตามฉันค้นพบบางสิ่งที่อาจนำคุณไปในทิศทางที่ถูกต้อง

1) ด้วยตัวเองแบบสอบถามเมตานี้จะเท่ากับ "colours IS NULL" นั่นคือมันจะส่งคืนโพสต์ที่ไม่มีชุดคีย์นั้นในตาราง postmeta นี่เป็นกรณีที่แสดงไว้ด้านบนและควรได้ผล

'meta_query' => array(
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS' // this should work...
    ),
)

2) ก่อนหน้า WordPress 3.9 สร้างดัชนี 'ความสัมพันธ์' เป็น 'หรือ' การเปลี่ยนแปลงเงื่อนไขนี้ มันส่งคืนสิ่งที่ตรงกันข้าม อย่าถามฉันทำไม สิ่งนี้มีความสำคัญอย่างยิ่งเมื่อทำแบบสอบถามหลายรายการ ซึ่งหมายความว่าเป็นไปไม่ได้ที่จะเริ่มค้นหาข้อความที่มีการตั้งค่าคีย์ 'สี' เป็น 'สีฟ้า' (หรืออะไรก็ตาม) หรือไม่ได้ตั้งค่าเลย การค้นหาด้านล่างจะไม่สนใจเงื่อนไขแรกและคืนเฉพาะรายการที่ตรงกับเงื่อนไขที่สอง

'meta_query' => array(
   'relation' => 'OR',
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS' // doesn't work
    ),
    array(
     'key' => 'colors',
     'value' => 'blue'
    )
)

3) อย่างไรก็ตามเราสามารถหลอก WordPress ให้ใช้เงื่อนไขแรกได้ถ้าเราตั้งค่า 'value' ไม่จำเป็นต้องมีค่าที่เกี่ยวข้อง (มันถูกละเว้นเท่าที่ฉันรู้) แต่จะต้องมีการตั้งค่าเพื่อให้NOT EXISTSเงื่อนไขมีผลกระทบใด ๆ

'meta_query' => array(
   'relation' => 'OR',
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS', // works!
     'value' => '' // This is ignored, but is necessary...
    ),
    array(
     'key' => 'colors',
     'value' => 'blue'
    )
)

สิ่งนี้เป็นจริงจนกระทั่ง WordPress 3.9 หากคุณยังคงใช้เวอร์ชั่นที่เก่ากว่านี่เป็นวิธีแก้ไขที่ใช้ได้จริง


ขอบคุณ! และขออภัยในความล่าช้า ฉันลงเอยด้วยการใช้แบบสอบถาม แต่ฉันจะทดสอบโซลูชันของคุณในเวลาต่อไปนี้เพื่อให้ฉันสามารถสลับกลับมาได้และบางทีถ้างานนี้เราสามารถช่วยเหลือคนอื่นได้ ฉันจะแจ้งให้คุณทราบทันทีที่ฉันสามารถตรวจสอบได้ ขอขอบคุณอีกครั้ง
JordanBel

เขียนได้ดีและยืนยันว่าการเพิ่มค่าว่างจะส่งกลับผลลัพธ์ที่คาดหวัง ฉันบอกว่ามันไม่ได้ตั้งใจอาจจะคุ้มค่ากับการดูที่ trac.wordpress.org เพื่อดูว่ามีตั๋วอยู่แล้วหรือไม่ถ้าไม่ใช่นี่จะทำซ้ำได้
Taylor Dewey

ขอบคุณสำหรับคำอธิบายและวิธีแก้ปัญหาที่ยอดเยี่ยมในการหลอกลวง WP :) ใช้เวลาสักครู่เพื่อรับที่นี่ - แต่ตอนนี้ฉันต้องการคลิก upvote อย่างน้อย 10 ครั้ง (ถ้าทำได้เท่านั้น)
ลิง lorem ลิง

ถ้าฉันใช้ EXISTS เปรียบเทียบค่าจะไม่ถูกละเว้นใน WP รุ่นที่ใหม่กว่า (ทดสอบใน 4.2.2)
Igor Jerosimić

10
EXISTSและNOT EXISTS"ข้อผิดพลาด" ซึ่งจำเป็นต้องให้คุณระบุค่าได้รับการแก้ไขใน WP 3.9
trex005

11

ใช้แบบสอบถามที่กำหนดเองนี้ทำงานให้ฉัน:

SELECT * FROM wp_posts as posts
            WHERE   posts.post_type     = 'post'
            AND NOT EXISTS (
              SELECT * FROM `wp_postmeta`
               WHERE `wp_postmeta`.`meta_key` = "your_meta_key"
                AND `wp_postmeta`.`post_id`=posts.ID
            ) 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.