Мета-запит із бульним значенням true / false


11

Я намагаюся показати всі властивості оренди, спочатку всі властивості, які не були орендовані, а потім усі властивості, які зараз орендуються. Існує спеціальний тип публікації "орендувати" зі спеціальним метам публікації для орендованої ціни (_price_rented), яка є галочкою (повертає або істинну, або хибну ... правда, якщо вона була орендована). Мені потрібно змінити запит, щоб показати всі властивості із наявними (не орендованими) властивостями, що з’являються спочатку, а потім з'являються орендовані властивості.

Ось мій запит:

$ts_properties = new WP_Query( 
    array( 
    'post_type' => 'rent', 
    'paged' => $paged, 
    'posts_per_page' => -1,
    'meta_key' => '_price_rented',
    'orderby' => 'meta_value',
    'order' => 'DESC',
    'meta_query' => array(
        array(
        'key' => '_price_rented',
        'value' => false,
        'type' => 'BOOLEAN',
        ),
    ) 
) 
);

Чомусь цей запит відображає всі властивості, які ВИ були орендовані. Коли я перемикаю значення з "false" на "true" у meta_query, воно не показує властивостей.

Отже, тоді я подумав, що повернене значення є або хибним (для властивостей, які АРЕНДАЮТЬ), або NULL (для властивостей, які НЕ здаються в оренду), але я не впевнений, як запитувати результат NULL (не помилковий), я додав ' порівняйте аргумент "meta_query" та встановіть значення "! =", але це не спрацювало.

EDIT: var_dump повертає наступне для доступної, не зданої в оренду квартири: string(0) ""і для квартири, яка не є в оренді, здається в оренду:string(1) "1"


можливо, використовуючи значення 1 і 0?
reikyoushin

meta_query type => рядок. Можливі значення "NUMERIC", "BINARY", "CHAR", "DATE", "DATETIME", "DECIMAL", "SIGNED", "TIME", "UNIGNED". Значення за замовчуванням - "CHAR".
iEmanuele

@reikyoushin: використання "1" повертає всі орендовані властивості, а "0" не повертає жодних властивостей.
Kegan Quimby

1
@iEmanuele: зміни, які, здається, не мають ефекту (я думав те саме). Я побачив це з цієї статті: thethemefoundry.com/blog/…
Kegan Quimby

1
Є чи на _price_rentedсамому справі встановити для обох trueі falseзначень, або вона встановлюється тільки для true? Перевірте, будь ласка, базу даних. Я запитав, оскільки прапорець без прапорець взагалі не пропускається, POSTтому мені цікаво, чи встановлено значення взагалі для цих випадків.
s_ha_dum

Відповіді:


4

WP_Meta_Query є якось "не настільки стабільною" частиною в ядрі, і якщо ви не приділяєте багато уваги, це може легко зламатися від плутанини.

Коли ви робите , new WP_Query()і є meta_query => array()аргументи або його один ключ / значення в перерахунок на пару, а потім new WP_Meta_Query()стрибає, відразу після чого розбору.

$this->meta_query = new WP_Meta_Query();
$this->meta_query->parse_query_vars( $q );

Дозволені значення

Коли ви запитуєте метадані, є boolваріант. І якщо ви використовуєте його, то воно повернеться до CHAR, яке значення за замовчуванням як масив дозволених значень:

'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'

де NUMERICбудуть скинуті в SIGNED.

Налагодження

Існує численні фільтри, які можуть впливати на процес збереження після публікації, тому перше, що потрібно зробити, це перевірити різні значення всередині певного циклу:

var_dump( get_post_meta( get_the_ID(), '_price_rented', true ) );

Потім, в залежності від значення, що повертається, ви повинні або використовувати SIGNED, якщо результат 0або 1, або , "true"або , "false"якщо результат є рядком. Якщо воно справді булеве, то я б все-таки запропонував використовувати stringлише для того, щоб переконатися, що він проходить $GLOBALS['wpdb'], який може пропускати лише %sрядок і %dцифру.

додаткові нотатки

Як я тільки що обновив запис Кодексу наWP_Meta_Query сьогоднішній день, я побачив , що там вже багато різних виходів (додавання численної кількості непотрібного JOINS, які обговорюються на Trac тут і тут з з одного патча переміщається в ядро) можливо. (Наступний квиток на ANDчастину тут ) Точка є те , що це можна використовувати комбінацію meta_*аргументів поряд з meta_queryмасивом і його подрешеток. Результат майже невідомий, якщо ви не скидаєте його, тому IMHO вам краще використовувати той чи інший спосіб додавання входів. Особливо, коли ти лишевикористовуючи meta_key, оскільки це призводить до "запиту лише з ключовими словами" в деяких випадках.

Рішення

Як зазначено в коментарях:

(...) var_dumpповертає для наявної, не зданої string(0) ""в оренду квартири:string(1) "1"

Тепер meta_queryдоводиться користуватися

'meta_query' => array( 'relation' => 'OR', array(
    'meta_key'     => '_price_rented',
    'meta_value'   => '1',
    'meta_compare' => '='
) );

Якщо ви хочете отримати "недоступні, орендовані квартири" або скористайтеся '!='для отримання "не зданих" в оренду квартир.

Примітка. Можливі значення для meta_compareє '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP'або 'RLIKE'. Значення за замовчуванням - '='.


3

Я зіткнувся з тією ж проблемою і після години пошуку знайшов "NOT EXISTS"і "EXISTS"значення ( only in WP >= 3.5 ). Тому не потрібно просити мета-значення, просто перевірте, чи існує мета-ключ:

'meta_key'     =>   '_price_rented'  ,
'meta_compare' =>   'NOT EXISTS'     ,

Це прекрасно працює для мене.


3

TL; DR: Ця проблема, ймовірно, здебільшого виникає, коли булеве поле створюється як необов'язкове. Ви можете виправити його, зробивши його необхідним, або скориставшись складнішим запитом для отримання випадку за замовчуванням.

Детальніше:

Тут виникають дві проблеми представлення даних: одна - які значення даних використовуються для відображення істинного / хибного, а друга - чи зберігається поле взагалі, якщо це значення за замовчуванням (як правило, помилкове).

Частина 1: Я переглянув SQL, сформований WP_Meta_Queryдля порівняння з істинним та хибним, і виявив, що для істинного він замінює '1' та 'false' '(порожній рядок). Тому все, що ви пишете в базу даних, повинно погоджуватися з цим, якщо ви збираєтеся робити запити, порівнюючи фактичні істинні та помилкові значення. Зокрема, ви не хочете писати "0" за помилкове. Можливо, більш безглуздо писати замість цього тест на 0 і 1 (і це роблять багато будівельників форм). Але перевірте, що записується в базу даних, і пам’ятайте про це, будуючи запит.

Частина 2: Якщо припустити, що false є значенням за замовчуванням, пошук записів, значення яких є правдивим, є простим:

... 'meta_key' => 'my_key', 'meta_value' => 1 (або правда)

Але інша сторона кидає виклик: може бути помилковим значенням або взагалі не бути значенням. Це може статися, якщо значення було вказане як необов’язкове у формі --- тоді, поки користувач не встановить його явно чи не змінить, воно не буде додане до бази даних. Зауважте, що якщо ви лише користуєтесь get_post_metaцим, то воно буде спрацьовувати нормально таким чином: повернення помилкового значення та повернення жодного значення не виконають те саме.

Але коли ви користуєтесь WP_Query, це не так просто. (Або якщо це так, я ще не зрозумів, як це зробити).

У вас є два (а може і три) варіанти:

  1. Переконайтесь, що поле завжди явно ініціалізовано до реального значення. У деяких конструкторах форм ви робите це, роблячи поле необхідним і надаючи йому значення за замовчуванням. Тоді ви можете ...'meta_value' => 0 надійно протестувати .

  2. Зробіть два запити, перший, який перевіряє помилкове значення, а другий - тестує значення без значення. Вони можуть бути об'єднані в один WP_Query на зразок цього:

    meta_query => {
        relation => 'OR'
        array(
            'key'     => 'my_key',
            'value'   => 0,
            'compare' => '='
        ),
        array(
            'key'     => 'my_key',
            'compare' => 'NOT EXISTS',
        ),
    )

Це, мабуть, не ефективний запит. Залежно від безлічі факторів, можливо, буде краще повернути всі об'єкти та відфільтрувати їх у власному коді.

  1. Можна використовувати "без значення", щоб означати хибність. Для цього щоразу, коли значення повинно бути встановлено на значення false, ви повинні видалити мета-значення замість оновлення .

У такому випадку один 'NOT EXISTS'запит надійно поверне правильні об’єкти. (Я не думаю, що багато розробників форм або плагінів підтримують таку поведінку, тому я використовую її лише у суто власному коді.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.