by Ben Stinton - 20th May 2015
Parent Child relationships in ElasticSearch have some big disadvantages, which mean they will never be as widely used as with a relational database. For example;
The child must exist on the same shared as the parent, therefore the parent must be created before the child. This make it impractical to have long chains of relationships.
They only support one parent, i.e. OneToMany. ManyToMany is not possible
it’s really hard to filter child results by a parent’s data, for example sorting a table of people by the name of the company they work for.
They can have a negative impact on query speed.
Even with this there are some use cases. For example a parent with many many children, if you need to use some of the parent data in a search of the child’s index then this can save time, especially if the children are quite large documents individually.
These settings apply to Symfony2.5, FOSElastica 3.0.9 and Elasticsearch 1.4.4. The first thing to do is to update your mapping with a _parent field declaration under the child, specifying parent type, the name of the property in the child that points to the parent, and the identifier in the parent.
Here is the relevent section from my mapping:
- #fos elastica
- index_name: index_%kernel.environment%
- client: default
- type: "long"
- type: company
- property: company
- identifier: id
- # required: true
- # path: company
- RoutingMissingException[routing is required for [index_v2]/[job]/]
Note that to create a document with a parent, you need to call setParent on the document rather than setting a _parent field. If you do this wrong, you will see a RoutingMissingException as Elasticsearch does not know where to store a document that should have a parent but does not specify it.
- #just above
- return $document
- class: Alpha\RMSBundle\Transformer\JobToElasticaTransformer
- - [ setPropertyAccessor, ['@fos_elastica.property_accessor'] ]