There's more...

In Elasticsearch, we have different ways to manage relations between objects, as follows:

  • Embedding with type=object: This is implicitly managed by Elasticsearch and it considers the embedding as part of the main document. It's fast, but you need to reindex the main document to change a value of the embedded object.
  • Nesting with type=nested: This allows for more accurate search and filtering of the parent using nested queries on children. Everything works for the embedded object except for query (you must use a nested query to search for them).
  • External children documents: Here, the children are the external document, with a join_field property to bind them to the parent. They must be indexed in the same shard as the parent. The join with the parent is a bit slower than the nested one, because the nested objects are in the same data block of the parent in Lucene index and they are loaded with the parent, otherwise, the child document requires more read operations.

Choosing how to model the relation from objects depends on your application scenario.

There is also another approach that can be used, but on big data documents, it brings poor performances—it's decoupling join relation. You do the join query in two steps: first, you collect the ID of the children/other documents and then you search for them in a field of their parent.