Truy vấn meta với giá trị boolean true / false


11

Tôi đang cố gắng hiển thị tất cả các tài sản cho thuê, trước tiên là bởi tất cả các tài sản chưa được thuê, và sau đó bởi tất cả các tài sản hiện đang được thuê. Có một loại bài đăng tùy chỉnh 'thuê' với meta bài đăng tùy chỉnh cho giá được thuê (_price_rents) là một hộp kiểm (trả về đúng hoặc sai ... đúng nếu nó đã được thuê). Tôi cần thay đổi truy vấn để hiển thị tất cả các thuộc tính với các thuộc tính có sẵn (không thuê) xuất hiện đầu tiên và sau đó các thuộc tính được thuê xuất hiện.

Đây là truy vấn của tôi:

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

Vì một số lý do, truy vấn này hiển thị tất cả các thuộc tính đã được thuê. Khi tôi chuyển giá trị từ 'false' thành 'true' trong meta_query, nó không hiển thị bất kỳ thuộc tính nào.

Vì vậy, sau đó tôi nghĩ, giá trị trả về là sai (đối với các thuộc tính được thuê) hoặc NULL (đối với các thuộc tính KHÔNG được thuê), nhưng không chắc chắn làm thế nào để truy vấn kết quả NULL (không sai), tôi đã thêm một ' so sánh 'đối số với meta_query và đặt giá trị thành'! = 'nhưng điều đó cũng không hoạt động.

EDIT: var_dump trả về những điều sau đây cho một căn hộ có sẵn, không thuê: string(0) ""và cho một căn hộ không có sẵn, được thuê:string(1) "1"


sử dụng giá trị 1 và 0 có lẽ?
reikyoushin

loại meta_query => chuỗi. Các giá trị có thể là 'SỐ', 'BINary', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'ĐĂNG KÝ', 'TIME', 'UNSIGNED'. Giá trị mặc định là 'CHAR'.
iEmanuele

@reikyoushin: sử dụng '1' trả về tất cả các thuộc tính được thuê và '0' không trả về các thuộc tính.
Kegan Quimby

1
@iEmanuele: thay đổi dường như không có tác dụng (tôi nghĩ điều tương tự). Tôi thấy điều đó từ bài viết này: thethemefoundry.com/blog/ Kẻ
Kegan Quimby

1
_price_rentedthực sự được đặt cho cả hai truefalsegiá trị, hoặc nó chỉ được đặt cho true? Vui lòng kiểm tra cơ sở dữ liệu. Tôi đã hỏi bởi vì một hộp kiểm không được kiểm tra hoàn toàn không được thông qua POSTvì vậy tôi tự hỏi liệu giá trị đó có được đặt ở tất cả các trường hợp đó không.
s_ha_dum

Câu trả lời:


4

WP_Meta_Query là một phần "không ổn định" nào đó trong cốt lõi và nếu bạn không chú ý nhiều đến việc giới thiệu nó có thể dễ dàng bị phá vỡ khỏi bị nhầm lẫn.

Khi bạn đang thực hiện một new WP_Query()và có các meta_query => array()đối số hoặc các cặp khóa / giá trị tương đương của nó, sau đó new WP_Meta_Query()nhảy vào, ngay lập tức theo sau là phân tích cú pháp.

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

Giá trị được phép

Khi bạn truy vấn dữ liệu meta, sau đó có booltùy chọn. Và nếu bạn sử dụng nó, thì nó sẽ quay trở lại CHAR, giá trị mặc định là mảng các giá trị được phép là:

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

nơi NUMERICsẽ được thiết lập lại SIGNED.

Gỡ lỗi

Có nhiều bộ lọc có thể ảnh hưởng đến quá trình lưu bài đăng, vì vậy điều đầu tiên cần làm là kiểm tra các giá trị khác nhau trong một số vòng lặp:

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

Sau đó, tùy thuộc vào giá trị trả về, bạn sẽ phải sử dụng SIGNED, nếu kết quả là 0hoặc 1, "true"hoặc "false"nếu kết quả là một chuỗi. Nếu nó thực sự là boolean, thì tôi vẫn khuyên bạn chỉ nên sử dụng stringđể đảm bảo nó vượt qua $GLOBALS['wpdb'], chỉ có thể truyền %schuỗi và %dchữ số qua.

Ghi chú bổ sung

Như tôi đã chỉ cần cập nhật các mục Codex choWP_Meta_Query ngày hôm nay, tôi thấy rằng có rất nhiều đang đầu ra khác nhau (thêm nhiều loại hình đa không cần thiết JOINS, mà sẽ được thảo luận trên Trác ở đâyở đây với ra một bản vá đơn chuyển sang lõi) càng tốt. (Theo dõi vé cho ANDcác bộ phận ở đây ) Điểm có thể sử dụng kết hợp các meta_*đối số bên cạnh meta_querymảng và các phần con của nó. Kết quả là khá nhiều người chưa biết trừ khi bạn kết xuất nó, vì vậy IMHO tốt hơn hết là sử dụng một hoặc cách khác để thêm đầu vào. Đặc biệt là khi bạn chỉsử dụng meta_key, vì điều này dẫn đến một "truy vấn chỉ khóa" trong một số trường hợp.

Giải pháp

Như đã chỉ ra trong các ý kiến:

(...) var_dumptrả lại những điều sau đây cho một căn hộ có sẵn, không thuê: string(0) ""và cho một căn hộ không có sẵn, được thuê:string(1) "1"

Bây giờ meta_queryphải sử dụng

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

Nếu bạn muốn có được "căn hộ không có sẵn, thuê" hoặc sử dụng '!='để lấy lại căn hộ "không thuê".

Lưu ý: Các giá trị có thể có meta_compare'=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP'hoặc 'RLIKE'. Giá trị mặc định là '='.


3

Tôi đã đối mặt với cùng một vấn đề và sau một giờ tìm kiếm đã tìm thấy "NOT EXISTS""EXISTS"giá trị ( only in WP >= 3.5 ). Vì vậy, không cần yêu cầu giá trị meta, chỉ cần kiểm tra xem meta_key có tồn tại không:

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

Nó hoạt động hoàn hảo đối với tôi.


3

TL; DR: Vấn đề này có lẽ chủ yếu xảy ra khi một trường boolean được tạo dưới dạng tùy chọn. Bạn có thể khắc phục bằng cách yêu cầu hoặc sử dụng truy vấn phức tạp hơn để truy xuất trường hợp mặc định.

Thêm chi tiết:

Có hai vấn đề biểu diễn dữ liệu đang diễn ra ở đây: một là giá trị dữ liệu đang được sử dụng để thể hiện đúng / sai và vấn đề còn lại là liệu trường có được lưu trữ hay không nếu đó là giá trị mặc định (thường là sai).

Phần 1: Tôi đã xem xét SQL được tạo ra WP_Meta_Queryđể so sánh với đúng và sai và thấy rằng đối với sự thật, nó thay thế '1' và sai '' (chuỗi trống). Vì vậy, bất cứ điều gì bạn viết vào cơ sở dữ liệu cần phải đồng ý với điều đó nếu bạn sẽ thực hiện các truy vấn so với giá trị đúng và sai thực tế. Cụ thể, bạn không muốn viết '0' cho sai. Thay vào đó, việc viết và kiểm tra 0 và 1 có thể dễ dàng hơn (và nhiều người xây dựng biểu mẫu làm điều đó). Nhưng hãy kiểm tra xem những gì đang được ghi vào cơ sở dữ liệu và ghi nhớ điều đó khi xây dựng truy vấn của bạn.

Phần 2: Giả sử sai là giá trị mặc định, việc tìm các bản ghi có giá trị là đúng là dễ dàng:

... 'meta_key' => 'my_key', 'meta_value' => 1 (hoặc đúng)

Nhưng mặt khác là thách thức: có thể có một giá trị sai hoặc có thể không có bất kỳ giá trị nào cả. Điều này có thể xảy ra nếu giá trị được liệt kê là tùy chọn trong một biểu mẫu --- sau đó miễn là người dùng không đặt nó rõ ràng hoặc thay đổi nó, nó sẽ không được thêm vào cơ sở dữ liệu. Lưu ý rằng nếu bạn chỉ sử dụng get_post_metanó sẽ hoạt động tốt theo cách này: trả về giá trị sai và trả về không có giá trị sẽ hoàn thành điều tương tự.

Nhưng khi bạn đang sử dụng WP_Query, nó không dễ dàng như vậy. (Hoặc nếu có, tôi vẫn chưa tìm ra cách nào).

Bạn có hai (hoặc có thể ba) tùy chọn:

  1. Đảm bảo rằng trường luôn được khởi tạo rõ ràng thành một giá trị thực. Trong một số trình tạo biểu mẫu, bạn thực hiện việc này bằng cách tạo trường bắt buộc và cung cấp cho nó một giá trị mặc định. Sau đó, bạn có thể kiểm tra ...'meta_value' => 0 đáng tin cậy.

  2. Thực hiện hai truy vấn, lần đầu tiên kiểm tra giá trị sai và truy vấn thứ hai kiểm tra không có giá trị. Chúng có thể được kết hợp thành một WP_Query như thế này:

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

Đây có lẽ không phải là một truy vấn hiệu quả. Tùy thuộc vào rất nhiều yếu tố, có thể tốt hơn là trả về tất cả các đối tượng và lọc chúng trong mã của riêng bạn.

  1. Có thể sử dụng 'không có giá trị' có nghĩa là sai. Để làm điều này, bất cứ khi nào giá trị được đặt thành false, bạn phải xóa giá trị meta thay vì cập nhật nó.

Trong trường hợp đó, một 'NOT EXISTS'truy vấn duy nhất sẽ trả về các đối tượng chính xác. (Tôi không nghĩ nhiều người xây dựng biểu mẫu hoặc plugin hỗ trợ hành vi này, vì vậy tôi chỉ sử dụng nó trong mã tùy chỉnh hoàn toàn.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.