Smart Nested Populate
MikroORM is capable of loading large nested structures while maintaining good 
performance, querying each database table only once. Imagine you have this nested 
structure:
Bookhas onePublisher(M:1), oneAuthor(M:1) and manyBookTags (M:N)Publisherhas manyTests (M:N)
When you use nested populate while querying all BookTags, this is what happens in
the background:
const tags = await orm.em.findAll(BookTag, ['books.publisher.tests', 'books.author']);
console.log(tags[0].books[0].publisher.tests[0].name); // prints name of nested test
console.log(tags[0].books[0].author.name); // prints name of nested author
- Load all 
BookTags - Load all 
Books associated with previously loadedBookTags - Load all 
Publishers associated with previously loadedBooks - Load all 
Tests associated with previously loadedPublishers - Load all 
Authors associated with previously loadedBooks 
You can also populate all relationships by passing
populate: true.
For SQL drivers with pivot tables this means:
SELECT `e0`.* FROM `book_tag` AS `e0`;
SELECT `e0`.*, `e1`.`book_id`, `e1`.`book_tag_id`
  FROM `book` AS `e0` LEFT JOIN `book_to_book_tag` AS `e1` ON `e0`.`id` = `e1`.`book_id`
  WHERE `e1`.`book_tag_id` IN (?, ?, ?, ?, ?)
  ORDER BY `e1`.`id` ASC;
SELECT `e0`.* FROM `publisher` AS `e0` WHERE `e0`.`id` IN (?, ?, ?);
SELECT `e0`.*, `e1`.`test_id`, `e1`.`publisher_id`
  FROM `test` AS `e0` LEFT JOIN `publisher_to_test` AS `e1` ON `e0`.`id` = `e1`.`test_id`
  WHERE `e1`.`publisher_id` IN (?, ?, ?)
  ORDER BY `e1`.`id` ASC;
SELECT `e0`.* FROM `author` AS `e0` WHERE `e0`.`id` IN (?);
For mongo driver its even simpler as no pivot tables are involved:
db.getCollection("book-tag").find({}).toArray();
db.getCollection("book").find({"tags":{"$in":[...]}}).toArray();
db.getCollection("publisher").find({"_id":{"$in":[...]}}).toArray();
db.getCollection("test").find({"_id":{"$in":[...]}}).toArray();
db.getCollection("author").find({"_id":{"$in":[...]}}).toArray();
Using EntityLoader manually
Under the hood, EntityManager uses EntityLoader to populate other entities. You can use it manually if you already have list of entities (e.g. queried via QueryBuilder):
import { EntityLoader } from 'mikro-orm';
const loader = new EntityLoader(orm.em);
const res = await orm.em.createQueryBuilder(Author).select('*').execute();
const authors = res.map(data => orm.em.merge(Author, data));
await loader.populate(Author, authors, ['books.tags']);
// now your Author entities will have `books` collections populated, 
// as well as they will have their `tags` collections populated.
console.log(authors[0].books[0].tags[0]); // initialized BookTag