Как запросить сущности без значения для определенного поля?
С помощью 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')
, но безуспешно.
2 answers
Реализация SQL EntityFieldQuery не поддерживает это, потому что она строит запрос с использованием INNER JOIN
s вместо LEFT JOIN
s. Я считаю это ошибкой, пожалуйста, откройте проблему в основной очереди.
Переопределите запрос 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".
Вот и все.