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 的 destid1
和 sourceid1
以及我的公司 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.
希望通过查询和加入来加入多个节点。假设一个节点具有另一个节点中另一个字段的匹配 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 的 destid1
和 sourceid1
以及我的公司 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.