Как запросить сущности без значения для определенного поля?


С помощью EntityFieldQuery довольно легко запрашивать сущности с заданным значением для определенного поля. Но я не могу найти способ запросить сущности без значения для данного поля. Допустим, у меня есть необязательное справочное поле таксономии для всех моих типов контента. Я могу запросить узлы, связанные с данным термином таксономии, используя:

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'file')
  ->fieldCondition('field_tags', 'tid', $tid)
  ->pager($limit);
$results = $query->execute();

Но как бы я запросил все узлы, не связанные с какими-либо терминами (т. Е. которые не имеют значения для field_tags поле). Я попытался установить $tid на NULL и $query->fieldCondition('field_tags', 'tid', $all_tids, 'NOT IN'), но безуспешно.

 4
Author: herci, 2011-07-18

2 answers

Реализация SQL EntityFieldQuery не поддерживает это, потому что она строит запрос с использованием INNER JOINs вместо LEFT JOINs. Я считаю это ошибкой, пожалуйста, откройте проблему в основной очереди.

 3
Author: Damien Tournoud, 2011-08-02 10:24:07

Переопределите запрос entityfieldкласса:

class GrabberEntityFieldQuery extends \EntityFieldQuery
{
    protected $absent = array();

    function finishQuery($select_query, $id_key = 'entity_id')
    {
        if ($this->age == FIELD_LOAD_CURRENT) {
            $tablename_function = '_field_sql_storage_tablename';
            $id_key = 'entity_id';
        }
        else {
            $tablename_function = '_field_sql_storage_revision_tablename';
            $id_key = 'revision_id';
        }

        $table_aliases = array();

        reset($this->fields);
        $key = key($this->fields);
        $field = current($this->fields);
        $tablename = $tablename_function($field);
        $field_base_table = $tablename . $key;

        $key = count($this->fields) + 1;

        foreach($this->absent as $field) {
            $tablename = $tablename_function($field);
            // Every field needs a new table.
            $table_alias = $tablename . $key;
            $table_aliases[$key] = $table_alias;

            $select_query->leftJoin(
                $tablename,
                $table_alias,
                "$table_alias.entity_type = $field_base_table.entity_type AND $table_alias.$id_key = $field_base_table.$id_key"
            );

            $select_query->where("$table_alias.$id_key IS NULL");

            $key++;
        }

        return parent::finishQuery($select_query, $id_key);
    }

    public function absentFieldCondition($field) {
        $field_definition = field_info_field($field);
        $this->absent[] = $field_definition;
    }
}

Использование:

$query = new GrabberEntityFieldQuery();
$query
    ->entityCondition('entity_type', 'node')
    ->deleted(FALSE);

// absent field
$query->absentFieldCondition('non_existent_field_name');

Будут выбраны узлы без поля "non_existent_field_name".

Вот и все.

 0
Author: Vitaly Fadeev, 2014-11-07 11:12:06