Loại trừ các trường trống (Null) khi sử dụng điều kiện truy vấn EntityFieldQuery


31

Có thể chọn tất cả các thực thể mà trường xyz trống không?

Tôi đã thử những thứ như thế này:

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

Tuy nhiên, điều này dường như không hoạt động.

Có ý kiến ​​gì không?

Câu trả lời:


19

Nếu bạn xem trên trang tài liệu fieldCondition, bạn sẽ thấy cảnh báo sau:

Lưu ý rằng các thực thể có giá trị trường trống sẽ bị loại trừ khỏi kết quả EntityFieldQuery khi sử dụng phương thức này.

Kiểm tra xem một trường có tồn tại hay không đã được thêm vào entityFieldQuery trong Drupal 8, nhưng không may là sẽ không được nhập vào Drupal 7 .

Có nhiều phương pháp khác nhau để đạt được điều này:

  1. Sử dụng thẻ và hook_queryiah_alter như được đề cập bởi @Clive, xem bình luận 4 về vấn đề Drupal để biết ví dụ;
  2. Trước tiên, truy vấn tất cả các mục không phải là NULL, sau đó truy vấn tất cả các mục không bao gồm các mục trước đó, như được mô tả trong câu trả lời của @ seddonymous và trong nhận xét 5 về vấn đề Drupal ;
  3. Bạn có thể viết truy vấn của mình bằng cách sử dụng SelectQuery rathen thay vì EntityfieldQuery như sau:

_

$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

Bạn có thể sử dụng != NULL, nhưng bạn không thể sử dụng = NULLvì một số lý do.

Đây là cách giải quyết của tôi.

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

Theo tài liệu bạn có thể sử dụng null và isnull; Nó chỉ có một cách cụ thể để viết nó.

$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

Câu trả lời ngắn gọn là trực tiếp, không bạn không thể (xem EntityFieldQuery không hỗ trợ isNull hoặc isNotNull ). Nếu tôi nhớ không nhầm thì đây là tác dụng phụ của thực tế là EntityFieldQuerychỉ sử dụng INNER JOINs để nối các bảng.

Tuy nhiên, có một cách giải quyết, bao gồm việc sử dụng hook_query_TAG_alter()và thêm thẻ vào thẻ của bạn EntityFieldQuery, có một ví dụ trong nhận xét cuối cùng trên trang tôi liên kết ở trên.


5

Trong Drupal 7, vui lòng kiểm tra cách giải quyết sau đây được đề xuất ở đây :

Đăng ký thẻ để thay đổi thể hiện truy vấn:

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

Quan sát: Thay đổi thẻ truy vấn này chỉ hoạt động cho loại thực thể "nút". Đừng nhầm lẫn "field_tags" liên quan đến từ vựng "Thẻ", có thể là bất kỳ từ nào khác như "Danh mục".

Nhận tất cả các nút từ đó chưa được gắn thẻ bằng EntityFieldQuery, hãy xem phương thức addTag ():

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

Ví dụ khác:

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

Sau đó, tôi đã triển khai hook_query_TAG_altertận dụng thực tế my_custom_tagchỉ do tôi đặt ra:

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

Một vi dụ khac:

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

Ví dụ đầy đủ hơn dưới đây tải một loạt các nút trên tác vụ cron mà tham chiếu thuật ngữ phân loại trống và áp dụng một số thay đổi:

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

Bạn cần phải bọc Null trong dấu ngoặc kép.

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

2

Hãy sửa lại cho tôi nếu tôi sai. Có vẻ như nó chỉ đơn giản là cần phải

$query->fieldCondition('field_name');

để loại trừ tất cả các nút có field_nametrường trống o_O

Đã thử nghiệm ở Drupal version >= 7.43.


Điều đó thực sự hoạt động. Họ trả lời nhiều hơn đã trả lời lỗi cho tôi (không thể để nó hiển thị lỗi, nhưng đã phá vỡ mọi thứ).
Joren
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.