Estou trabalhando em um projeto no qual estou criando um tipo de postagem personalizado e dados personalizados inseridos por meio de meta boxes associadas ao meu tipo de postagem personalizada. Por alguma razão, decidi codificar as meta boxes de forma que as entradas em cada metabox fizessem parte de uma matriz. Por exemplo, estou armazenando longitude e latitude:
<p>
<label for="latitude">Latitude:</label><br />
<input type="text" id="latitude" name="coordinates[latitude]" class="full-width" value="" />
</p>
<p>
<label for="longitude">Longitude:</label><br />
<input type="text" id="longitude" name="coordinates[longitude]" class="full-width" value="" />
</p>
Por qualquer motivo, gostei da ideia de ter uma entrada pós-meta singular para cada metabox. No save_post
gancho, eu salvo os dados da seguinte forma:
update_post_meta($post_id, '_coordinates', $_POST['coordinates']);
Fiz isso porque tenho três metaboxes e gosto de ter apenas 3 valores pós-meta para cada postagem; no entanto, agora percebi um problema em potencial com isso. Talvez eu queira usar o WP_Query para extrair apenas determinadas postagens com base nesses meta-valores. Por exemplo, eu posso querer obter todas as postagens com valores de latitude acima de 50. Se eu tivesse esses dados no banco de dados individualmente, talvez usando a chave latitude
, faria algo como:
$args = array(
'post_type' => 'my-post-type',
'meta_query' => array(
array(
'key' => 'latitude',
'value' => '50',
'compare' => '>'
)
)
);
$query = new WP_Query( $args );
Como tenho a latitude como parte do _coordinates
postmeta, isso não funcionaria.
Então, minha pergunta é: existe uma maneira de utilizar meta_query
para consultar uma matriz serializada como eu tenho neste cenário?
fonte
Eu também encontro essa situação. Aqui o que eu fiz:
Espero que esta ajuda
fonte
$value
também é um ID. Nesse caso, sugiro criar funções para adicionar um caractere a cada elemento da matriz antes de salvar os dados e outra função para remover o caractere antes de usar os dados. Dessa forma, oi:2
índice serializado não será confundido com osi:D2
dados "reais". O parâmetro de meta consulta deve se tornar'value' => sprintf(':"D%s";', $value),
e você manterá a funcionalidade correta dessa resposta maravilhosa!LIKE
é uma maneira excelente e rápida de derrubar o servidor (sem mencionar falsos positivos); é melhor você ter um cache muito bom.Você realmente perderá a capacidade de consultar seus dados de qualquer maneira eficiente ao serializar entradas no banco de dados do WP.
A economia e o ganho geral de desempenho que você acha que está alcançando pela serialização não serão notados em grande parte. Você pode obter um tamanho de banco de dados um pouco menor, mas o custo das transações SQL será alto se você consultar esses campos e tentar compará-los de qualquer maneira útil e significativa.
Em vez disso, salve a serialização para dados que você não pretende consultar dessa natureza, mas acessaria apenas de forma passiva pela chamada direta da API do WP
get_post_meta()
- a partir dessa função, é possível descompactar uma entrada serializada para acessar também as propriedades da matriz.De fato, atribuiu o valor de true como em;
$meta = get_post_meta( $post->ID, 'key', true );
Retornará os dados como uma matriz, acessível para você repetir normalmente.
Você pode se concentrar em outras otimizações de banco de dados / site, como cache, minificação CSS e JS e usar esses serviços como uma CDN, se necessário. Para citar apenas alguns .... O WordPress Codex é um bom ponto de partida para descobrir mais sobre esse tópico: AQUI
fonte
Acabei de lidar com campos serializados e poderia consultá-los. Não usando a meta_query, mas usando uma consulta SQL.
A consulta primeiro pesquisa por postagem com o post_type correspondente, para que a quantidade de registros wp_postmeta seja menor para filtrar. Em seguida, adicionei uma instrução where para reduzir ainda mais as linhas filtrando
meta_key
Os IDs acabam bem em uma matriz, conforme necessário para get_posts.
PS. É necessário o MySQL v5.6 ou superior para obter um bom desempenho da subconsulta
fonte
Este exemplo realmente me ajudou. É especificamente para o plug-in S2Members (que serializa os metadados do usuário). Mas permite consultar uma parte de uma matriz serializada dentro da meta_key.
Funciona usando a função REGEXP do MySQL.
Aqui está a fonte
Aqui está o código que consulta todos os usuários que vivem nos EUA. Modifiquei-o facilmente para consultar um dos meus campos de registro personalizados e o funcionou rapidamente.
fonte
Eu acho que existem 2 soluções que podem tentar resolver o problema dos resultados sendo armazenados como String e Inteiros. No entanto, é importante dizer, como outros apontaram, que não é possível garantir a integridade dos resultados armazenados como Inteiro, porque, como esses valores são armazenados como matrizes serializadas, o índice e os valores são armazenados exatamente com o mesmo padrão. Exemplo:
é armazenado como uma matriz serializada, como esta
Observe
i:0
como a primeira posição da matriz ei:37
como o primeiro valor. O padrão é o mesmo. Mas vamos às soluções1) Solução REGEXP
Esta solução funciona para mim, independentemente do meta-valor que está sendo salvo como string ou número / ID. No entanto, ele usa
REGEXP
, o que não é tão rápido quanto usarLIKE
2) COMO A Solução
Não tenho certeza sobre a diferença de desempenho, mas esta é uma solução que usa
LIKE
e também funciona para números e seqüências de caracteresfonte
REGEXP
é legal em certas situações, mas se você pode usarLIKE
, acho que é o método preferível. Um link antigo, mas ainda bastante útil, na minha opinião: thingsilearn.wordpress.com/2008/02/28/... :-)LIKE
é mais rápido. Mas esta é uma solução que funciona para ambas as cordas e númerosLIKE
mas funciona para números e seqüências de caracteres. Eu não tenho certeza sobre o desempenho porque tem que comparar os resultados usandoOR
Depois de ler várias dicas para executar uma
WP_Query
filtragem por matrizes serializadas, eis como finalmente o fiz: criando uma matriz de valores separados por vírgula usando implode em conjunto com uma$wpdb
consulta SQL personalizada que utilizaFIND_IN_SET
para pesquisar o valor solicitado na lista separada por vírgula.(isso é semelhante à resposta de Tomas, mas é um pouco menos eficiente para a consulta SQL)
1. Em functions.php:
No seu arquivo functions.php (ou onde quer que você esteja configurando a meta box) na
yourname_save_post()
função usepara criar a matriz que contém valores separados por vírgula.
Você também deseja alterar sua variável de saída na
yourname_post_meta()
função de construção da caixa de administração para2. No arquivo PHP de modelo:
Teste: se você executar um,
get_post_meta( $id );
deverá vercheckboxArray
como uma matriz que contém seus valores separados por vírgula, em vez de uma matriz serializada.Agora, criamos nossa consulta SQL personalizada usando
$wpdb
.Observe o
FIND_IN_SET
, é aí que a mágica acontece.Agora ... desde que eu estou usando
SELECT *
isso retorna todos os dados de postagem e dentro do queforeach
você pode fazer eco do que você quer (faça umprint_r($posts);
se você não souber o que está incluído. Ele não configura "o loop" para você (eu prefiro assim), mas pode ser facilmente modificado para configurar o loop, se você preferir (dê uma olhada nosetup_postdata($post);
codex, você provavelmente precisará alterarSELECT *
para selecionar apenas IDs de postagem e$wpdb->get_results
o$wpdb
tipo correto - - veja o codex$wpdb
também para obter informações sobre esse assunto).Whelp, demorou um pouco de esforço, mas como
wp_query
não suporta'compare' => 'IN'
valores serializados ou separados por vírgula, esse calço é a melhor opção!Espero que isso ajude alguém.
fonte
Se você usar o
like
operador de comparação em sua meta consulta, ele deverá funcionar bem para procurar dentro de uma matriz serializada.resulta em:
fonte
Se meus metadados forem do tipo array, eu uso este método para consulta por meta:
fonte
Fiquei curioso sobre as respostas acima, onde o
meta_query
alvo a chave emlatitude
vez de_coordinates
. Tive que testar se realmente era possível, nas meta-consultas, segmentar uma chave específica dentro de uma matriz serializada. :)Obviamente não era esse o caso.
Portanto, observe que a chave correta para segmentar é em
_coordinates
vez delatitude
.NOTAS:
Essa abordagem torna possível apenas segmentar correspondências exatas. Portanto, coisas como todas as latitudes maiores que 50 não são possíveis.
Para incluir correspondências de substring, pode-se usar
'value' => sprintf(':"%%%s%%";', $value),
. (não testei)fonte
Eu tenho a mesma pergunta. Talvez você precise do parâmetro 'type'? Confira esta pergunta relacionada: Consulta de campo personalizado - Meta Value is Array
Talvez tente:
fonte
Encontrei algo semelhante ao usar o plug-in Magic Fields. Isso pode fazer o truque
fonte
serialize()
não é necessária neste caso ...