EntityTypeManager for querying nodes

Almost every day I come across the need to quickly grab a few node IDs matching certain criteria. Sometimes I need a list of all the articles with a specific tag, sometimes I need to find a specific node of my custom type room by node ID. There are always many ways to go about this in Drupal, the easiest usually being to create a custom view. I won't cover that here, that's not what this post is about. What if you need this list in a preprocess function, or custom module?

EntityTypeManager queries are what I've been using for queries. Once you catch on to the pattern, they are super easy. Let's look at a couple easy examples.

Get all articles

Starting with a simple query, we'll get a list of all published articles.

use \Drupal\node\Entity\Node;

$storage = \Drupal::entityTypeManager()->getStorage('node');
$query = $storage->getQuery()
  ->condition('type', 'article')
  ->condition('status', Node::PUBLISHED)
  ->execute();

In this example, $query will return an array of node IDs. For me, it looks like this:

Array(2) {
  [10]=> string(1) "2"
  [12]=> string(1) "1"
}

Our query has returned two nodes with IDs of 1 and 2. I won't go into detail in this post about what to do with the result, but as a quick example, here is how you would go about loading those nodes:

if (!empty($query)) {
  $entities = $storage->loadMultiple($query);

  // $entities will be an array of loaded node objects.
}

Get specific articles with field conditions

While that above use case in pretty simple and generic, more often than not you'll need to get specific in your query parameters to get the data you actually want. Below is a way to find more specific articles based on several field conditions.

use \Drupal\node\Entity\Node;

$storage = \Drupal::entityTypeManager()->getStorage('node'); 
$query = $storage->getQuery()
  ->condition('type', 'article')
  ->condition('status', Node::PUBLISHED)
  ->condition('field_tags', '4', 'IN')
  ->condition('field_teaser', NULL, 'IS NOT NULL')
  ->sort('created', 'DESC')
  ->execute();

In this query, we are looking for all articles that are published, have a tag with the term ID of 4, have the field teaser where the value is not empty, and then is sorted by date posted (newest first). If you change the IN or IS NOT NULL you can perform opposite queries to the one we just wrote. As before, this returns an array of node IDs.

Posted March 30th, 2020
Tested againstDrupal 8.8.4