meta_query compare = ‘! =’ com vários campos personalizados

uma postagem possui os seguintes campos personalizados:

'my_custom_field' => 1 'my_custom_field' => 2 'my_custom_field' => 3 

Agora eu quero consultar todas as postagens que NÃO possuem o valor 2 para ‘my_custom_field’. Estou tentando isso:

 $args = Array('posts_per_page' => -1, 'post_type' => 'page', 'meta_query' => array( array( 'key' => 'my_custom_field', 'value' => 2, 'compare' => '!=' ) ) ); 

No entanto, isso ainda está retornando a minha mensagem de exemplo, pois minha publicação de exemplo tem um campo de ‘my_custom_field’ com um valor diferente de 2 (1 e 3). Eu de alguma forma preciso alterar minha consulta para dizer “Excluir mensagens que tenham pelo menos um campo de ‘my_custom_field’ com o valor de 2”.

Alguém pode me ajudar? Obrigado!

Solutions Collecting From Web of "meta_query compare = ‘! =’ com vários campos personalizados"

Isso pode exigir a escrita sql personalizada com uma subconsulta:

 $results = $wpdb->get_results(" SELECT * FROM $wpdb->posts WHERE ID NOT IN ( SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'my_custom_field' and meta_value = 2 ) "); 

então basta iterar através dos resultados como descrito aqui .

Como @TomJNowell e @s_ha_dum dizem que você em comentários, no seu caso provavelmente uma taxonomia personalizada é melhor do que campos personalizados, porque é muito fácil obter uma publicação que não tenha um termo de taxonomia.

Dito isto, eu entendo que se você tiver um monte de código que o Alreadt escreveu, ou você está trabalhando com código de terceiros, mudar para taxonomia personalizada pode ser difícil / não é possível.

Aswer fornecido por @elleeott funciona, no entanto, não é flexível, porque você não pode alterar mensagens por página, meta valor, etc.

Eu lhe fornecerei uma solução semelhante, mas um pouco mais flexível e você pode ajustá- la para atender às suas necessidades.

Essencialmente é apenas uma class que estende WP_Query e aplique filtros para solicitar o desempenho do que você deseja

 class MyMetaQuery extends WP_Query { protected $do_posts_request_filter = TRUE; function get_posts() { $this->query_vars['suppress_filters'] = FALSE; // force do filters add_action( 'posts_request', array( $this, 'filter_request' ), 999 ); parent::get_posts(); $this->do_posts_request_filter = FALSE; // run only once } /* build the sql request */ function filter_request( $request ) { if ( ! $this->do_posts_request_filter ) return $request; $q = $this->get('meta_query'); if ( empty($q) || ! is_array($q) || ! isset($q[0]['key']) ) return $request; global $wpdb; $k = $q[0]['key']; $v = isset( $q[0]['value'] ) ? $q[0]['value'] : ''; if ( is_array( $v ) ) $v = implode( ',', $v ); $mcompare = isset( $q[0]['compare'] ) ? $q[0]['compare'] : 'IN'; if ( ! in_array( $mcompare, array('IN', 'NOT IN', '=', '!=') ) ) { $mcompare = 'IN'; } if ( $mcompare === '!=' ) $mcompare = 'NOT IN'; if ( $mcompare === '=' ) $mcompare = 'IN'; $ppage = $this->get('posts_per_page') ? : get_option('posts_per_page'); $limit = $wpdb->prepare(' LIMIT %d', $ppage); if ( substr_count( $limit, '-1' ) ) $limit = ''; if ( $limit && $this->get('nopaging') ) $limit = ''; $type_compare = 'IN'; $type = $this->get('post_type') ? : 'post'; if ( is_array( $type ) ) $type = implode(',', $type ); if ( $type === 'any' ) { $type_compare = 'NOT IN'; $status = '-1'; } $status_compare = 'IN'; $status = $this->get('post_status') ? : 'publish'; if ( is_array($status) ) $type = implode(',', $status); if ( $status === 'any' ) { $status_compare = 'NOT IN'; $status = '-1'; } $query = " SELECT SQL_CALC_FOUND_ROWS $wpdb->posts.* FROM $wpdb->posts INNER JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id WHERE post_type $type_compare (%s) AND post_status $status_compare (%s) AND $wpdb->postmeta.meta_key = %s AND ID NOT IN ( SELECT DISTINCT post_id FROM $wpdb->postmeta WHERE meta_key = %s and CAST(meta_value AS CHAR) $mcompare (%s) ) "; return $wpdb->prepare( $query, $type, $status, $k, $k, $v ) . $limit; } } 

Depois disso, ao invés de usar o WP_Query você precisa usar a class MyMetaQuery :

 $args = array( 'posts_per_page' => -1, 'post_type' => 'page', 'meta_query' => array( array( 'key' => 'my_custom_field', 'value' => 2, 'compare' => '!=' ) ) ); $query = new MyMetaQuery( $args ); if ( $query->have_posts() ) { while( $query->have_posts() ) { $query->the_post(); // do what you want here } wp_reset_postdata(); } 

Observe que é o único padrão que a class personalizada aceita são:

  • 'post_type' , pode ser um único tipo, uma seqüência separada por vírgulas ou uma variedade de tipos ou ‘qualquer’
  • 'post_status' pode ser um status único, uma seqüência separada por vírgulas ou uma matriz de status ou ‘qualquer’
  • 'posts_per_page' pode ser um número positivo ou ‘-1’
  • 'nopaging' pode ser TRUE ou FALSE . Definir para TRUE irá retornar todas as postagens sobre a posição ‘posts_per_page’
  • 'meta_query' aceita uma multidimensional array, assim como WP_Query . Observe que você só pode passar uma matriz de consulta, qualquer consulta adicional será ignorada. A matriz de consulta aceita como chaves de matriz: 'key' , 'value' e 'compare' . 'value' pode ser um único valor, uma seqüência separada por vírgulas ou uma matriz de valores. 'compare' pode ser ‘IN’ , ‘NOT IN’ , ‘=’ e ‘! =’

Se você precisar de outros argumentos (categoria, tags, taxonomias, data, etc.), você deve ampliar os resources da class ou, mais provavelmente, usar outra abordagem.