# HPOS 订单查询 API

随着 HPOS 的引入，我们增强了 WC 中的查询功能。现在，除了众所周知的 [现有 API](/docs/extensions/core-concepts/wc-get-orders)，我们添加了一些功能，可以更轻松地创建复杂的订单或其属性的查询，包括查询自定义订单元数据的能力。

所有新的查询类型都实现为额外的查询参数，这些参数可以传递给 `wc_get_orders()` 函数，并且深受 WordPress 自己的 `WP_Query` 中类似功能的启发。 像常规的查询参数一样，它们可以与其他参数组合，以生成复杂的查询，而这些查询在过去需要编写自定义代码和 SQL。

## 新的查询类型

### 元数据查询 (`meta_query`)

随着 HPOS 的引入，以前存储为帖子元数据的订单字段已移动到其自己的表中，但剩余的元数据（自定义或来自其他扩展）现在可以通过 `meta_query` 参数进行查询。

从根本上说，`meta_query` 是一个数组，它可以包含一个或多个具有以下键的数组：
`key` (元数据键名)，
`value` (元数据值)
`compare` (可选) 用于比较的运算符，例如 LIKE、RLIKE、NOT BETWEEN、BETWEEN 等。
`type` 用于在查询中将元数据值转换为特定的 SQL 类型。

不同的数组还可以使用 `relation`（允许 'AND' 或 'OR' 值）组合起来，以生成更复杂的查询。 此新参数的语法与 `WP_Query` 的 `meta_query` 完全相同。 因此，您可以参考 [`meta_query` 文档](https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters)，以获取更多详细信息。

```php
// 示例：获取所有具有 "color" 键的元数据的订单（任何值），以及具有 "size" 键且包含 "small" 的元数据的订单（例如，也会匹配 "extra-small"）。
$orders = wc_get_orders(
    array(
        'meta_query' => array(
            array(
                'key' => 'color',
            ),
            array(
                'key'        => 'size',
                'value'      => 'small',
                'compare'    => 'LIKE'
            ),
        ),
    )
);
```

### 订单字段查询 (`field_query`)

这种查询类型具有与元查询 (`meta_query`) 相似的语法，但它使用 `field` 替代 `key`，在不同的子句中使用 `field`。 在这里，`field` 指的是任何订单属性（例如 `billing_first_name`、`total` 或 `order_key` 等），这些属性也可以像往常一样作为顶级键在查询参数中访问。 直接查询这些属性与使用 `field_query` 之间的区别在于，您可以通过实现比较运算符以及组合或嵌套来创建更复杂的查询。

```php
// 示例。 对于简单的查询，最好直接使用订单属性，即使存在 `field_query` 的等效方法。
$orders = wc_get_orders(
    array(
        'billing_first_name' => 'Lauren',
        'order_key'          => 'my_order_key',
    )
);

$orders = wc_get_orders(
    array(
        'field_query' => array(
            array(
                'field' => 'billing_first_name',
                'value' => 'Lauren'
            ),
            array(
                'field' => 'order_key',
                'value' => 'my_order_key',
            )
        )
    )
);
```

`field_query` 的真正强大之处在于，当您想要执行更复杂的查询时，这些查询以前是无法实现的。

```php
// 示例。 获取所有总价或配送总价小于 5.0 的订单。

$orders = wc_get_orders(
    array(
        'field_query' => array(
            'relation' => 'OR',
            array(
                'field'   => 'total',
                'value'   => '5.0',
                'compare' => '<',
            ),
            array(
                'field'   => 'shipping_total',
                'value'   => '5.0',
                'compare' => '<',
            ),
        )
    )
);
```

### 日期查询 (`date_query`)

日期查询允许您通过查询与其关联的日期（`date_completed`、`date_created`、`date_updated`、`date_paid`）以各种方式来获取订单。
`date_query` 的语法与 `WP_Query` 中的 `date_query` 完全兼容。 因此，一个很好的示例和详细信息的来源是 [WP 代码库中的 `meta_query` 文档](https://developer.wordpress.org/reference/classes/wp_query/#date-parameters)。

```php
// 示例。 获取所有在过去一个月内支付的，并且在任何日期之前创建的订单。

$orders = wc_get_orders(
    array(
        'date_query' => array(
            'relation' => 'AND',
            array(
                'column'  => 'date_created_gmt',
                'hour'    => 12,
                'compare' => '<'
            ),
            array(
                'column'  => 'date_paid_gmt',
                'after'   => '1 month ago',
            ),
        ),
    )
);
```

## 高级示例

```php
// 获取状态为 "on-hold" 或 "pending"，且元数据 `weight` >= 50，并且元数据 `color` 或 `size` 存在的订单。

$query_args = array(
    'status' => array( 'pending', 'on-hold' ),
    'meta_query' => array(
        array(
            'key'     => 'weight',
            'value'   => '50',
            'compare' => '>=',
        ),
        array(
            'relation' => 'OR',
            array(
                'key'     => 'color',
                'compare' => 'EXISTS',
            ),
            array(
                'key'     => 'size',
                'compare' => 'EXISTS',
            )
        ),
    )
);

$orders = wc_get_orders( $query_args );
```

```php
// 获取在账单详情中，名包含 "laur" 的订单（例如，匹配 "lauren" 和 "laura"），并且订单总额小于 10.0，且总折扣 >= 5.0。

$orders = wc_get_orders(
    array(
        'field_query' => array(
            array(
                'field'   => 'billing_first_name',
                'value'   => 'laur',
                'compare' => 'LIKE',
            ),
            array(
                'relation' => 'AND',
                array(
                    'field'   => 'total',
                    'value'   => '10.0',
                    'compare' => '<',
                    'type'    => 'NUMERIC',
                ),
                array(
                    'field'   => 'discount_total',
                    'value'   => '5.0',
                    'compare' => '>=',
                    'type'    => 'NUMERIC',
                )
            )
        ),
    )
);
```