Drupal实体查询多种节点类型并加入

Drupal entityQuery multiple node types and join

希望通过查询和加入来加入多个节点。假设一个节点具有另一个节点中另一个字段的匹配 ID。我想将它们连接到一个数组中,这样我就可以输出其他字段,它们在同一个 ID 上被索引在一起。示例:node1.nid 和 node2.field.target_id

我该怎么做?

$nids = \Drupal::entityQuery('node')->accessCheck(FALSE)
->join('node2', 'n2', 'n.nid = n2.field.target_id');
->condition('type', 'node1', 'node2')
->sort('title')->execute();

$nodes = \Drupal\node\Entity\Node::loadMultiple($nids);

$response = array(); 

这绝对是可行的,看起来你就快完成了,但看起来你正在将数据库 API 与实体 API 结合起来,特别是试图 运行 数据库加入 EntityQuery 提取。

现在,如果你想继续数据库查询路线,这可能会使连接多个实体的值并输出它们更容易一些,这是我推荐的:

我注意到的第一件事是您正在尝试链接连接。不幸的是,根据 Database API Docs

Joins cannot be chained, so they have to be called separately (see Chaining).

我在两个自定义内容类型之间进行了类似的连接。这是我使用的代码:

   $connection = Database::getConnection();
   if ($connection->schema()->tableExists('companies') && $connection->schema()->tableExists('users')) {
      $query = $connection->select('companies', 'c');
      $query->join('users', 'u', 'c.sourceid1 = u.sourceid1');
      $results = $query->fields('u', ['destid1', 'sourceid1'])
        ->fields('c', ['destid1'])
        ->execute()
        ->fetchAll();

      return $results;
    }

现在假设您已经引入了 Drupal\Core\Database\Database,但让我们来看看这个过程。

$connection = Database::getConnection();

这是为您的站点获取数据库连接

if ($connection->schema()->tableExists('companies') && $connection->schema()->tableExists('users')) {

这是我经常做的一项检查,以确保我正在使用的 tables 存在。

$query = $connection->select('companies', 'c');

您的 table 之一需要作为“基础”table。在这种情况下,我选择了companies

$query->join('users', 'u', 'c.sourceid1 = u.sourceid1');

这一行是连接实际发生的地方。请注意,它不是链接的,而是自己的命令。我们将在这个 sourceid1 上加入这些 table 用户和公司。

      $results = $query->fields('u', ['destid1', 'sourceid1'])
        ->fields('c', ['destid1'])
        ->execute()
        ->fetchAll();

这是我从两个实体中提取我想要的任何字段的地方。在这种情况下,我想要我的用户 table 的 destid1sourceid1 以及我的公司 table.

destid1

->execute() 调用实际上是 运行 查询, ->fetchAll() return 是所有匹配结果的数组。这将使您能够对所有内容进行 JSONify。

但是,如果您想坚持使用 entityQuery 路由,那也是可行的。我个人的偏好是对更复杂的事物使用常规查询,如果我只需要从单个字段或 return 单个实体获取值,则使用 entityQuery。

对于 entityQuery,有点不同。我真的不建议在这里使用 entityQuery 进行连接。相反,如果您知道或可以从两个 table 中获得匹配值,则使用 entityTypeManager

例如,假设内容类型 A 的 field_content_type_a_id 与内容类型 B 的 field_related_type_a_id 匹配。

你可以加载一个,让我们现在使用 A 型:

// Get the current NID somehow... that's up to you
$entity_a = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
// Get the value of the field you want to match to the other content type
$matching_value = $entity_a->get('field_content_type_a_id')->getValue();
// Get the entities with matching type A values
$entity_b_array = \Drupal::entityTypeManager()->getStorage('node')
  ->loadByProperties(['field_related_type_a_id' => $matching_value]);

// Do something with $entity_b_array.