查询在给定范围内具有数值元值的帖子

时间:2013-12-08 作者:Robbert

我正在用WordPress建立一个租赁公司的网站。我很难找到在元字段中存储公寓可用性的好方法。具体而言,使游客能够在给定的日期范围内找到可用的公寓。

我想我会让中介机构在邮报编辑中选择公寓不可用的日期。我的第一个猜测是将日期存储在一个字符串中。对于从1月5日到1月7日不可用的示例列表,我将保留一个元记录,如下所示:

update_post_meta($post_id, "listing_unavailable", "/20140105/20140106/20140107/");
现在,当我寻找1月6日至1月11日的上市时间时。。。

$arrival_date   = 20140106;
$departure_date = 20140111;
。。。我将运行以下元查询:

$meta = [];

for($i = $arrival_date; $i <= $departure_date; $i++)
    $meta[] = array(
        "key"     => "listing_unavailable",
        "value"   => "/".$i."/",
        "compare" => "NOT LIKE"
    );

$query->set("meta_query", $meta);
元查询将返回给定范围内没有不可用日期的任何帖子。完美的然而,WordPress增加了一个JOIN 对于每个元查询,现在我们的日期范围非常有限。我认为SQL支持多达61个JOINs和我还有很多其他领域的访客可以过滤。所以我只能选择2到3周的范围,然后才能得到JOIN 限制错误。

所以我想,也许我应该把每个不可用的日期作为一个单独的值添加。例如,从5号到7号:

delete_post_meta($post_id, "listing_unavailable");
add_post_meta($post_id, "listing_unavailable", 20140105);
add_post_meta($post_id, "listing_unavailable", 20140106);
add_post_meta($post_id, "listing_unavailable", 20140107);
现在,我设想1月6日至1月11日的元查询如下所示:

$meta = array(
    "key"     => "listing_unavailable",
    "value"   => array($arrival_date, $departure_date),
    "compare" => "NOT BETWEEN",
    "type"    => "NUMERIC"
);
但这行不通。访问者现在仍然可以找到示例列表,因为1月5日不在"NOT BETWEEN" 范围,将示例视为列出了有效结果。

我似乎想不出使用标准WordPress函数来解决这个问题的正确设置,而不使SQL查询太重。有什么想法或建议吗?

1 个回复
最合适的回答,由SO网友:Robbert 整理而成

我最终在WordPress的能力范围内找到了两种解决方案。


存储可用日期而不是不可用日期,第一种解决方案是让机构选择所有可用日期,而不是选择不可用日期。然后,我们的示例列表将有一个自定义字段listing_available:

update_post_meta($post_id, "listing_available", "/20140101/20140102/20140103/20140104/");
然后我就可以运行以下命令LIKE 字段查询:

$dates = [];
for($i = $arrival_date; $i <= $departure_date; $i++)
    $dates[] = $i;

$meta = array(
    "key"     => "listing_available",
    "value"   => "/".implode("/", $dates)."/",
    "compare" => "LIKE"
);
到达和离开之间的所有日期必须在listing_available 要显示的列表的字段。对于问题中提供的示例,查询不会按预期找到列表,因为它在所有给定日期都不可用。

虽然这是可行的,但这意味着该机构必须定期更新所有帖子,因为帖子现在默认设置为不可用。此外,还必须为这项工作订购日期。


在深入研究的核心代码时,使用REGEXP比较类型WP_Meta_Query (元查询的主干)我发现了另外两种尚未记录的比较类型:REGEXPNOT REGEXP.

这些比较类型立即解决了我的问题,因为我现在可以在单个元字段中查找不同的值,而不必处理实际的查询。使用$dates 上述代码中的数组:

$regexp = "(/".implode("/|/", $dates)."/)";

$meta = array(
    "key"     => "listing_unavailable",
    "value"   => $regexp,
    "compare" => "NOT REGEXP"
);
现在,我可以在给定范围内的任何日期使用regex和(通过使用NOT) 如果日期匹配,则删除结果。

如果WP_Meta_Query 将支持设置OR 对于具有多个值的单个元查询,我可以使用LIKE.


我仍然想知道这是否是在没有繁重的SQL查询或复杂的查询更改函数的情况下过滤可用租金的最有效方法。如果有人知道解决这个问题的更有效的方法,我会选择它作为“最佳答案”。

结束