具有布尔值TRUE/FALSE的元查询

时间:2013-07-31 作者:Kegan Quimby

我试图显示所有租赁物业,首先显示所有尚未租赁的物业,然后显示所有当前租赁的物业。有一个自定义贴子类型“rent”,带有用于price Rendered(\\u price\\u Rendered)的自定义贴子元,这是一个复选框(如果已租用,则返回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\\u查询中将值从“false”切换到“true”时,它不会显示任何属性。

因此,我想,返回值要么为false(对于租用的属性)要么为NULL(对于未租用的属性),但不确定如何查询NULL结果(不是false),我在meta\\u查询中添加了一个“compare”参数,并将值设置为“!=”但这也没用。

编辑:var\\u dump为可用的非租赁公寓返回以下内容:string(0) "" 对于不可用的租赁公寓:string(1) "1"

3 个回复
SO网友:Denise Draper

TL;DR:当布尔字段被创建为可选字段时,可能会出现此问题。您可以通过使其成为必需的或使用更复杂的查询来检索默认情况来修复它。

更多详细信息:

这里存在两个数据表示问题:一个是使用哪些数据值表示真/假,另一个是如果字段是默认值(通常为假),则是否存储该字段。

第1部分:我研究了WP_Meta_Query 用于比较true和false,并发现对于true,它将“1”替换为false“”(空字符串)。因此,如果要对实际的真值和假值进行比较,那么无论您在数据库中写入什么,都需要与之一致。特别是,您不想将“0”写入false。相反,为0和1编写和测试可能更简单(许多表单生成器都这样做)。但要查看写入数据库的内容,并在构建查询时牢记这一点。

第2部分:假设默认值为false,查找值为true的记录很容易:

... \'meta_key\' => \'my_key\', \'meta_value\' => 1 (或真)

但另一方面是具有挑战性的:可能有一个错误的值,或者根本没有任何值。如果该值在表单中列为可选值,则可能发生这种情况,只要用户没有显式设置或更改它,它就不会添加到数据库中。请注意,如果您仅使用get_post_meta 这样就可以很好地工作:返回一个错误的值和不返回任何值将完成相同的事情。

但是当你使用WP_Query, 这并不是那么容易。(如果是的话,我还没有弄清楚是怎么回事)。

您有两个(或三个)选项:

确保字段始终显式初始化为实值。在某些表单生成器中,可以通过将字段设为必填字段并为其提供默认值来实现这一点。然后你可以测试...\'meta_value\' => 0 可靠。

执行两个查询,第一个测试是否存在错误值,第二个测试是否没有值。这些查询可以组合成一个单独的WP\\U查询,如下所示:

meta_query => array(
   \'relation\' => \'OR\',
    array(
        \'key\'     => \'my_key\',
        \'value\'   => 0,
        \'compare\' => \'=\'
    ),
    array(
        \'key\'     => \'my_key\',
        \'compare\' => \'NOT EXISTS\',
    ),
)
这可能不是一个有效的查询。根据许多因素,最好返回所有对象并在您自己的代码中过滤它们。

可以使用“no value”表示false。为此,每当值设置为false时,必须删除元值,而不是更新它\'NOT EXISTS\' 查询将可靠地返回正确的对象。(我认为许多表单生成器或插件都不支持这种行为,所以我只在纯自定义代码中使用它。)

SO网友:kaiser

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, 如果结果是01, 或"true""false" 如果结果是字符串。如果它真的是布尔值,那么我仍然建议使用string 只是为了确保它通过$GLOBALS[\'wpdb\'], 只能通过%s 字符串和%d 数字至。

我刚刚更新的其他注释the Codex entry for WP_Meta_Query 今天,我看到有很多不同的输出(添加了大量不需要的JOINS, 在Trac上讨论herehere 随着退出单个补丁移动到核心)可能。(后续票据AND 零件here) 关键是可以使用以下组合meta_*meta_query 阵列及其子阵列。除非将其转储,否则结果几乎未知,因此最好使用or 另一种添加输入的方法<尤其是当您仅使用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\'. 默认值为\'=\'.

SO网友:Thibaut

我也遇到了同样的问题,经过一个小时的搜索,我找到了"NOT EXISTS""EXISTS" 价值( only in WP >= 3.5 ).因此,无需询问meta值,只需检查meta\\u键是否存在:

\'meta_key\'     =>   \'_price_rented\'  ,
\'meta_compare\' =>   \'NOT EXISTS\'     ,
这对我来说非常有效。

结束

相关推荐

使用新的WP-Query()从循环中过滤后期格式;

嗨,我目前正在为我的博客构建一个主题。下面的代码指向最新的帖子(特色帖子)。因为这将有一个不同的风格比所有其他职位。然而我想过滤掉帖子格式:链接使用我在循环中定义的WP查询,因为它给我带来了更多的灵活性。我该怎么做呢? <?php $featured = new WP_Query(); $featured->query(\'showposts=1\'); ?> <?php while ($featured->have_post