it-swarm.com.de

Ausschließen leerer (Null-) Felder bei Verwendung der EntityFieldQuery-Abfragebedingung

Ist es möglich, alle Entitäten auszuwählen, deren xyz-Feld leer ist?

Ich habe so etwas versucht:

->fieldCondition('field_name', 'value', NULL, 'IS NOT NULL');

Dies scheint jedoch nicht zu funktionieren.

Irgendwelche Ideen?

30
David Barratt

Wenn Sie auf die Dokumentationsseite fieldCondition schauen, wird die folgende Warnung angezeigt:

Beachten Sie, dass Entitäten mit leeren Feldwerten bei Verwendung dieser Methode aus den EntityFieldQuery-Ergebnissen ausgeschlossen werden.

Überprüfen, ob ein Feld vorhanden ist oder nicht, wurde zu entityFieldQuery in Drupal 8, aber leider wird nicht nach Drupal 7 zurückportiert =.

Es gibt verschiedene Methoden, um dies zu erreichen:

  1. Verwenden Sie ein Tag und hook_query_TAG_alter, wie von @Clive erwähnt, siehe Kommentar 4 zum Problem Drupal für ein Beispiel;
  2. Fragen Sie zuerst alle nicht NULL-Einträge ab und dann alle Einträge mit Ausnahme der vorherigen, wie in der Antwort von @ seddonym und in Kommentar 5 zum Problem Drupal) ;
  3. Sie können Ihre Abfrage mit SelectQuery rathen als EntityfieldQuery als solches schreiben:

_

$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();
19
Alice Heaton

Sie können != NULL Verwenden, aber Sie können = NULL Aus irgendeinem Grund nicht verwenden.

Dies ist meine Problemumgehung.

  //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(); 
  }
15
seddonym

Die kurze Antwort lautet: Nein, das können Sie nicht (siehe EntityFieldQuery unterstützt isNull oder isNotNull nicht ). Wenn ich mich richtig erinnere, ist dies ein Nebeneffekt der Tatsache, dass EntityFieldQuery nur INNER JOIN S verwendet, um Tabellen zu verbinden.

Es gibt jedoch eine Problemumgehung, bei der hook_query_TAG_alter() verwendet und Ihrem EntityFieldQuery ein Tag hinzugefügt wird. Der letzte Kommentar auf der Seite, auf die ich verlinkt habe, enthält ein Beispiel über.

10
Clive

Laut Dokumentation Sie können null und isnull verwenden; Es gibt nur eine bestimmte Art, es zu schreiben.

$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);
}
10
giorgio79

In Drupal 7 überprüfen Sie bitte die folgende vorgeschlagene Problemumgehung hier :

Registrieren Sie das Tag, um die Abfrageinstanz zu ändern:

<?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');
}
?>

Hinweis: Diese Änderung des Abfragetags funktioniert nur für den Entitätstyp "Knoten". Verwechseln Sie nicht "field_tags" mit dem Vokabular "Tags", es kann sich auch um "Kategorien" handeln.

Mit EntityFieldQuery können Sie alle Knoten abrufen, die noch nicht markiert wurden. Schauen Sie sich die Methode addTag () an:

<?php
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'news')
  ->addTag('node_is_not_tagged')
  ->propertyCondition('status', 1);
$result = $query->execute();
?>

Anderes Beispiel:

  $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();

Dann habe ich hook_query_TAG_alter Implementiert und dabei die Tatsache genutzt, dass my_custom_tag Nur von mir festgelegt wird:

/**
 * 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');
}

Ein anderes Beispiel:

<?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();  
  }
?>

Vollständigeres Beispiel, in dem eine Reihe von Knoten auf eine Cron-Task geladen werden, die Taxonomie-Termreferenzen leeren und einige Änderungen anwenden:

/**
 * 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
}
5
kenorb

Sie müssen Null in Anführungszeichen setzen.

->fieldCondition('field_name', 'value', 'NULL', '!=');
3
Sharique

Bitte korrigieren Sie mich, wenn ich falsch liege. Es scheint, dass es einfach sein muss

$query->fieldCondition('field_name');

um alle Knoten mit einem leeren field_name Feld o_O auszuschließen

Getestet in Drupal version >= 7.43.

2
leymannx