web-dev-qa-db-ja.com

真偽値のメタ値

最初に賃貸されていないすべての物件で、次に現在賃貸されているすべての物件ですべての賃貸物件を表示しようとしています。チェックボックスであるカスタム賃貸料(_price_rented)のカスタム投稿メタを持つカスタム投稿タイプ 'rent'があります(trueまたはfalseを返します。レンタルされている場合はtrueを返します)。使用可能な(レンタルされていない)プロパティが最初に表示され、次にレンタルされたプロパティが表示されているすべてのプロパティを表示するようにクエリを変更する必要があります。

これが私の質問です:

$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',
        ),
    ) 
) 
);

何らかの理由で、このクエリはレンタルされたすべてのプロパティを表示します。 meta_queryで値を 'false'から 'true'に切り替えると、プロパティは表示されません。

そのため、戻り値はfalse(レンタルされているプロパティの場合)またはNULL(レンタルされていないプロパティの場合)のいずれかになりますが、NULLの結果をクエリする方法(falseではない)はわかりません。引数をmeta_queryと比較し、値を '!='に設定してもうまくいきませんでした。

EDIT:var_dumpは、賃貸可能な賃貸アパートの場合はstring(0) ""、賃貸不可能な賃貸アパートの場合はstring(1) "1"を返します。

8
Kegan Quimby

私は同じ問題に直面し、検索の1時間後に"NOT EXISTS""EXISTS"( only in WP >= 3.5 )を見つけました。したがって、meta_keyが存在するかどうかを確認するだけで、メタ値を要求する必要はありません。

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

それは私にとって完璧に働いています。

3
Thibaut

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'

ここで、NUMERICSIGNEDにリセットされます。

デバッグ

保存後プロセスに影響を与える可能性のあるフィルターは多数あるため、最初に行うことは、ループ内で異なる値をチェックすることです。

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

次に、戻り値に応じて、結果が0または1の場合はSIGNEDを使用する必要があります。または"true"または"false"の場合結果は文字列です。本当にブール値の場合、$GLOBALS['wpdb']文字列と%s数字のみを渡すことができる%dを確実に渡すために、stringを使用することをお勧めします。

その他の注意事項

WP_Meta_QueryのCodexエントリ を更新したところ、さまざまな出力がたくさんあることがわかりました(不要なJOINSが大量に追加されていますTrac ここ および ここでる 単一のパッチがコアに移動しました)。 (ANDパーツのチケットをフォロー ここで )ポイントは、meta_*引数の組み合わせを一緒に使用できることですismeta_query配列とそのサブ配列。ダンプしない限り、結果はほとんどわからないので、IMHOどちらかを使用した方が良いでしょうまたは入力を追加する他の方法。 特にmeta_keyを使用するonlyの場合、これは場合によっては「キーのみのクエリ」になります。

溶液

コメントで指摘されているように:

(...)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
kaiser

TL; DR: この問題は、ブール型フィールドがオプションとして作成されている場合によく発生します。必要に応じて修正するか、より複雑なクエリを使用してデフォルトのケースを取得することで修正できます。

もっと詳しく

ここでは2つのデータ表現の問題があります。1つはtrue/falseを表すために使用されているデータ値、もう1つはデフォルト値(通常はfalse)の場合はフィールドがまったく格納されているかどうかです。

パート1:WP_Meta_Queryによって生成されたSQLを調べて、trueとfalseを比較しましたが、trueの場合は1、falseの場合は空の文字列になります。データベースに書き込むものはすべて、実際のtrue値とfalse値と比較しながらクエリを実行する場合は、それに同意する必要があります。特に、あなたは偽のために '0'を書きたくありません。代わりに0と1を書いてテストするほうがより確実かもしれません(そして多くのフォームビルダーがそうしています)。しかし、データベースに何が書き込まれているのかを確認し、クエリを作成するときにはそのことに留意してください。

パート2:falseがデフォルト値であると仮定すると、値がtrueであるレコードを見つけるのは簡単です。

... 'meta_key' => 'my_key', 'meta_value' => 1(またはtrue)

しかし、反対側はやりがいがあります。誤った値がある、またはまったく値がない可能性があります。これは、値がフォーム内でオプションとしてリストされている場合に発生する可能性があります。その場合、ユーザーが明示的に設定または変更しない限り、データベースに追加されません。 get_post_metaのみを使用しているのであれば、この方法で問題なく動作します。偽の値を返し、値を返さないことで同じことができます。

しかし、あなたがWP_Queryを使っているとき、それはそれほど簡単ではありません。 (あるいはそうだとすれば、私はまだどのように考え出していないか)。

2つ(または3つ)の選択肢があります。

  1. フィールドが常に明示的に実数値に初期化されていることを確認してください。一部のフォームビルダーでは、フィールドを必須にしてデフォルト値にすることでこれを行います。そうすれば...'meta_value' => 0を確実にテストすることができます。

  2. 2つのクエリを実行します。1つ目は偽の値をテストし、2つ目は値をテストしません。これらは、このように単一のWP_Queryに組み合わせることができます。

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

これはおそらく効率的なクエリではありません。多くの要因によっては、すべてのオブジェクトを返して自分のコードでフィルタ処理することをお勧めします。

  1. 偽を意味するために「値なし」を使用することは可能です。これを行うには、値をfalseに設定する必要があるときはいつでも、 更新 itの代わりに メタ値 を削除する必要があります。

その場合、単一の'NOT EXISTS'クエリは確実に正しいオブジェクトを返します。 (私は多くのフォームビルダーやプラグインがこの振る舞いをサポートしているとは思わないので、私は純粋にカスタムコードでのみそれを使用したいと思います。)

2
Denise Draper