É possível selecionar todas as entidades cujo campo xyz está vazio?
Eu tentei algo assim:
->fieldCondition('field_name', 'value', NULL, 'IS NOT NULL');
No entanto, isso não parece funcionar.
Alguma ideia?
É possível selecionar todas as entidades cujo campo xyz está vazio?
Eu tentei algo assim:
->fieldCondition('field_name', 'value', NULL, 'IS NOT NULL');
No entanto, isso não parece funcionar.
Alguma ideia?
Respostas:
Se você olhar na página de documentação do fieldCondition , verá o seguinte aviso:
Observe que entidades com valores de campos vazios serão excluídas dos resultados EntityFieldQuery ao usar esse método.
A verificação da existência ou não de um campo foi adicionada ao entityFieldQuery no Drupal 8, mas infelizmente não será suportada para o Drupal 7 .
Existem vários métodos para conseguir isso:
_
$q = db_select('node', 'n');
$q->fields('n', array('type'))
->condition('n.type', 'my_node_type', '=')
->addJoin('LEFT', 'field_data_field_my_field', 'f', 'f.entity_id = n.nid');
$q->isNull('f.value');
$r = $q->execute();
Você pode usar != NULL
, mas não pode usar = NULL
por algum motivo.
Esta é a minha solução alternativa.
//Get all the entities that DO have values
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'MY_TYPE')
->fieldCondition('field_MY_FIELD', 'value', 'NULL', '!=');
$result = $query->execute();
if (is_array(@$result['registration'])) {
//Now get all the other entities, that aren't in the list you just retrieved
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'MY_TYPE')
->entityCondition('entity_id', array_keys($result['MY_TYPE']), 'NOT IN');
$result_two = $query->execute();
}
De acordo com a documentação, você pode usar null e isnull; apenas tem uma maneira específica de escrevê-lo.
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'article')
->propertyCondition('status', 1)
->fieldCondition('field_news_types', 'value', 'spotlight', '=')
->fieldCondition('field_photo', 'fid', 'NULL', '!=')
->fieldCondition('field_faculty_tag', 'tid', $value)
->fieldCondition('field_news_publishdate', 'value', $year. '%', 'like')
->range(0, 10)
->addMetaData('account', user_load(1)); // run the query as user 1
$result = $query->execute();
if (isset($result['node'])) {
$news_items_nids = array_keys($result['node']);
$news_items = entity_load('node', $news_items_nids);
}
A resposta curta é que diretamente, não, você não pode (consulte EntityFieldQuery não suporta isNull ou isNotNull ). Se bem me lembro, esse é um efeito colateral do fato de que EntityFieldQuery
usa apenas INNER JOIN
s para juntar tabelas.
Existe uma solução alternativa, porém, que envolve o uso hook_query_TAG_alter()
e a adição de uma tag à sua EntityFieldQuery
, há um exemplo no último comentário na página que eu vinculei acima.
No Drupal 7, verifique a seguinte solução proposta aqui :
Registre a tag para alterar a instância da consulta:
<?php
/**
* Implements hook_query_TAG_alter()
*/
function MYMODULE_query_node_is_not_tagged_alter(QueryAlterableInterface $query) {
$query->leftJoin('field_data_field_tags', 'o', 'node.nid = o.entity_id AND o.entity_type = :entity_type');
$query->isNull('o.field_tags_tid');
}
?>
Obs .: Essa alteração da tag de consulta funciona apenas para o tipo de entidade "nó". Não confunda "tags de campo" relacionadas ao vocabulário "Tags", pois pode haver outras como "Categorias".
Obtenha todos os nós que ainda não foram marcados usando EntityFieldQuery, veja o método addTag ():
<?php
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'news')
->addTag('node_is_not_tagged')
->propertyCondition('status', 1);
$result = $query->execute();
?>
Outro exemplo:
$result = $query
->entityCondition('entity_type', 'node')
->propertyCondition('type', 'my_content_type')
->fieldCondition('field_mine_one', 'value', '', '<>')
->fieldCondition('field_mine_two', 'value', '', '<>')
->addTag('my_custom_tag')
->deleted(FALSE)
->propertyOrderBy('changed', 'DESC')
->range(0, $my_range_value)
->execute();
Então eu implementei,
hook_query_TAG_alter
aproveitando o fato quemy_custom_tag
é definido apenas por mim:
/**
* Implements hook_query_TAG_alter()
*/
function MYMODULE_query_TAG_alter(QueryAlterableInterface $query) {
$query->leftJoin('field_data_field_other', 'o', 'node.nid = o.entity_id');
$query->isNull('o.field_other_value');
}
Outro exemplo:
<?php
//Get all the entities that DO have values
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'MY_TYPE')
->fieldCondition('field_MY_FIELD', 'value', 'NULL', '!=');
$result = $query->execute();
if (is_array(@$result['registration'])) {
//Now get all the other entities, that aren't in the list you just retrieved
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'MY_TYPE')
->entityCondition('entity_id', array_keys($result['MY_TYPE']), 'NOT IN');
$result_two = $query->execute();
}
?>
Exemplo mais completo abaixo, que carrega vários nós na tarefa cron, que esvazia referências de termos de taxonomia e aplica algumas mudanças:
/**
* Implements hook_cron().
*/
function MYMODULE_cron() {
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'property')
->propertyOrderBy('changed', 'DESC')
->addTag('type_is_null')
->range(0,50); // Maximum of 50.
$result = $query->execute();
if (!empty($result['node'])) {
$nids = array_keys($result['node']);
$nodes = node_load_multiple($nids);
foreach ($nodes as $node) {
// do_some_stuff($node);
}
}
}
/**
* Implements hook_query_TAG_alter()
*/
function MYMODULE_query_type_is_null_alter(QueryAlterableInterface $query) {
$query->leftJoin('field_data_field_foo', 'f', 'node.nid = f.entity_id AND f.entity_type = :entity_type');
$query->isNull('f.field_foo_tid'); // Check name by SQL: DESC field_data_field_foo
$query->leftJoin('field_data_field_bar', 'b', 'node.nid = b.entity_id AND b.entity_type = :entity_type');
$query->isNull('b.field_bar_tid'); // Check name by SQL: DESC field_data_field_bar
}
Por favor me corrija se eu estiver errado. Parece que ele simplesmente precisa ser
$query->fieldCondition('field_name');
excluir todos os nós com um field_name
campo vazio o_O
Testado em Drupal version >= 7.43
.