Tidak termasuk bidang kosong (Null) saat menggunakan kondisi kueri EntityFieldQuery


31

Apakah mungkin untuk memilih semua entitas yang bidang xyznya kosong?

Saya mencoba sesuatu seperti ini:

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

Namun, ini sepertinya tidak berhasil.

Ada ide?

Jawaban:


19

Jika Anda melihat halaman dokumentasi fieldCondition Anda akan melihat peringatan berikut:

Perhatikan bahwa entitas dengan nilai bidang kosong akan dikecualikan dari hasil EntityFieldQuery saat menggunakan metode ini.

Memeriksa apakah ada lapangan atau tidak telah ditambahkan ke entityFieldQuery di Drupal 8, tetapi sayangnya tidak akan di-backport ke Drupal 7 .

Ada berbagai metode untuk mencapai ini:

  1. Menggunakan tag dan hook_query_TAG_alter seperti yang disebutkan oleh @Clive, lihat komentar 4 pada masalah Drupal sebagai contoh;
  2. Pertama, kueri semua entri non-NULL, lalu kueri semua entri kecuali yang sebelumnya, seperti yang dijelaskan dalam jawaban @ seddonym dan dalam komentar 5 tentang masalah Drupal ;
  3. Anda dapat menulis kueri menggunakan rathen SelectQuery daripada EntityfieldQuery seperti:

_

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

15

Anda dapat menggunakan != NULL, tetapi Anda tidak dapat menggunakan = NULLkarena suatu alasan.

Ini solusinya.

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

10

Menurut dokumentasi Anda dapat menggunakan null dan isnull; hanya memiliki cara khusus untuk menulisnya.

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

9

Jawaban singkatnya adalah bahwa secara langsung, tidak Anda tidak dapat (lihat EntityFieldQuery tidak mendukung isNull atau isNotNull ). Jika saya ingat benar ini adalah efek samping dari fakta yang EntityFieldQueryhanya menggunakan INNER JOINs untuk bergabung dengan tabel.

Namun, ada solusi yang melibatkan penggunaan hook_query_TAG_alter()dan penambahan tag pada Anda EntityFieldQuery, ada contoh di komentar terakhir pada halaman yang saya tautkan di atas.


5

Dalam Drupal 7 silakan periksa solusi berikut yang diusulkan di sini :

Daftarkan tag untuk mengubah instance kueri:

<?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 .: Perubahan tag permintaan ini hanya berfungsi untuk jenis entitas "node". Jangan bingung "field_tags" terkait dengan kosa kata "Tag", bisa berupa "Kategori" lainnya.

Dapatkan semua node dari yang belum ditandai menggunakan EntityFieldQuery, lihat metode addTag ():

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

Contoh lain:

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

Kemudian saya menerapkan hook_query_TAG_altermemanfaatkan fakta yang my_custom_taghanya saya tetapkan:

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

Contoh lain:

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

Contoh yang lebih lengkap di bawah ini yang memuat banyak node pada tugas cron yang mengosongkan referensi istilah taksonomi dan menerapkan beberapa perubahan:

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

3

Anda harus membungkus Null dengan tanda kutip.

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

2

Harap perbaiki saya jika saya salah. Tampaknya memang perlu begitu

$query->fieldCondition('field_name');

untuk mengecualikan semua node dengan field_namebidang kosong o_O

Diuji dalam Drupal version >= 7.43.


Itu benar-benar berfungsi. Mereka lebih banyak jawaban yang dibalik ternyata tidak cocok untuk saya (tidak bisa menampilkan kesalahan, tetapi merusak semuanya).
Joren
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.