Unable to set up Parent Child with FOSElasticaBundle - symfony

I am trying to setup a parent child relationship and I can't seem to get the mapping config right. I'm using Symfony2.5, FOSElastica 3.0.9 and Elasticsearch 1.4.4
Here is the relevent section from my mapping:
# fos elastica
fos_elastica:
clients:
default: { host: 127.0.0.1, port: 9200 }
serializer:
callback_class: FOS\ElasticaBundle\Serializer\Callback
serializer: serializer
indexes:
index:
index_name: index_%kernel.environment%
client: default
types:
company:
mappings:
id:
type: "long"
company_name:
type: "string"
fields:
raw:
type: "string"
index: "analyzed"
index_analyzer: "sortable"
persistence:
elastica_to_model_transformer:
ignore_missing: true
driver: orm # orm, mongodb, propel are available
model: Alpha\RMSBundle\Entity\Company
provider: ~
finder: ~
listener: ~
serializer:
groups: [company]
job:
mappings:
id:
type: "long"
company:
type: "object"
properties:
id:
type: "long"
_parent:
type: company
property: company
identifier: id
#_routing:
# required: true
# path: company
persistence:
elastica_to_model_transformer:
ignore_missing: true
driver: orm # orm, mongodb, propel are available
model: Alpha\RMSBundle\Entity\JobOpening
provider: ~
finder: ~
listener: ~
serializer:
groups: [job]
First I populate company, but when I try to populate job I get the following error:
[Elastica\Exception\ResponseException]
RoutingMissingException[routing is required for [index_v2]/[job]/[1]]
I have tried specifying the routing which is commented out above, but that didn't set the relationship either, I have taken the routing out as it is not mentioned in the docs.
Can anyone see where I am going wrong?

There is no problem with the mapping above, and _routing is not required. However FOSElastica will not populate the mapping with a _parent set.
However, as the docs says you need to to use setParent on the Document. In order to do this I need to setup a custom ModelToElasticaTransformer. This can be done by extending the ModelToElasticaAutoTransformer provided from the bundle in a class Alpha\RMSBundle\Transformer\JobToElasticaTransformer
In the transform() function I inserted a line:
$document->setParent($object->getCompany()->getId());
just above
return $document
Then you declare the service:
alpha.transformers.model.job:
class: Alpha\RMSBundle\Transformer\JobToElasticaTransformer
calls:
- [ setPropertyAccessor, ['#fos_elastica.property_accessor'] ]
Finally add the following in the mapping for the type in the persistence section:
model_to_elastica_transformer:
service: alpha.transformers.model.job
Now you can use populate as normal, as long as you remember to populate the parent class first

The bundle explains this very clearly in it's documentation
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.

Related

FOSElasticaBundle: Root mapping definition has unsupported parameters:

I get the following error when populating elastic search:
Root mapping definition has unsupported parameters: [product : {dynamic_date_formats=[], _meta={model=App\Entity\Product}, properties={name={type=text}, description={type=text}}}] [reason: Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters: [product : {
dynamic_date_formats=[], _meta={model=App\Entity\Product}, properties={name={type=text}, description={type=text}}}]]
Basically, I followed only the documentation ( https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/doc/setup.md ) and changed userto product and the corresponding fields in my App\Entity\Product.
fos_elastica.yaml:
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
app:
types:
product:
properties:
name: ~
description: ~
persistence:
driver: orm
model: App\Entity\Product
provider: ~
finder: ~
Are you using Elasticsearch version 7? I had the same problem today and think that it is related to the Elasticsearch version you are using.
If I install Elasticsearch version 6, everything is working fine.
I'm not an Elasticsearch expert, but there are probably some breaking changes in version 7 with which FOSElasticaBundle is not yet compatible.

How to use JMSSerializerBundle with Gedmo Timestampable

I am using JMSSerializerBundle with Symfony3. I am using TimestampableEntity trait. What I want to achieve is to receive that trait with JMSSerializer.
use Gedmo\SoftDeleteable\Traits\SoftDeleteableEntity;
use Gedmo\Timestampable\Traits\TimestampableEntity;
class Thread
{
use TimestampableEntity;
use SoftDeleteableEntity;
(...)
}
I have added metadata to the jms_serializer config like this:
config.yml
jms_serializer:
enable_short_alias: false # controls if "serializer" service is aliased to jms_serializer.serializer s
metadata:
directories:
- { path: "%kernel.root_dir%/Resources/Gedmo/serializer", namespace_prefix: 'Gedmo\Timestampable\Traits' }
\app\Reources:
Gedmo\Timestampable\Traits\TimestampableEntity:
exclusion_policy: ALL
properties:
created_at:
expose: true
But it is not working.
I know that I can configure it to use my Thread class and expose all necessary fields but I wonder if it is possible for traits.

FOSElasticaBundle & Propel

I have installed FOSElasticaBundle "friendsofsymfony/elastica-bundle": "^3.2"
(with symfony 2.8.8) and tried to define this simple configuration
fos_elastica:
clients:
default: { host: %elastic_host%, port: %elastic_port% }
indexes:
project:
types:
item:
mappings:
id: { type: integer }
itemno: { type: string }
persistence:
driver: propel
model: Model\Item\Item
provider: ~
Unfortunately I'm getting following error
The parent definition "fos_elastica.listener.prototype.propel" defined
for definition "fos_elastica.listener.project.item" does not
exist.
As I read through the documentation, there is no "listener" available for propel - that's why I'm a little bit confused about the error message. I already tried to define the missing definition, but with no result.
Is it necessary to define any class/service as provider for the type? In the documentation I couldn't find anything about that?
Thanks.

Unknown entity namespace in security.yml with custom entities folder in Symfony 2

I have my model entities saved in src/AppBundle/Model/Entity.
You can understand, that i have own custom folder for entities (in model folder).
This is my orm settings in config.yml:
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: false
mappings:
user:
type: annotation
dir: %kernel.root_dir%/../src/AppBundle/Model/Entity
alias: 'Entity'
prefix: AppBundle\Model\Entity
is_bundle: false
I have a problem with these lines in my security.yml:
providers:
our_db_provider:
entity:
class: AppBundle:User
property: username
# if you're using multiple entity managers
# manager_name: customer
There is some error:
Unknown Entity namespace alias 'AppBundle'.
I don't what ref I have to use (AppBundle:User probably not).
Thank you for your answers.
By default, all Symfony bundles will have a nice alias: XxxBundle (aliasing the NamespaceOfXxxBundle\Entity namespace). As you're bundle doesn't follow this convention and stores it in Model\Entity instead, you have 2 options:
Don't use the alias feature and pass the FQCN: AppBundle\Model\Entity\User
Create a new alias, give it a nice name and use it:
doctrine:
orm:
# ...
mappings:
user:
type: annotation
dir: %kernel.root_dir%/../src/AppBundle/Model/Entity
alias: App # <-- the alias name
prefix: AppBundle\Model\Entity
is_bundle: false
App:User

FosElasticaBundle: how to dump the actual JSON passed to ElasticSearch?

I am using FosElasticaBundle in a Symfony project. I configured my mappings but I get exception "expected a simple value for field [_id] but found [START_OBJECT]]".
I'd like to see the actual JSON created by FosElasticaBundle so I can directly test it against my ElasticSearch server, and understand more about the exception.
According to FosElastica documentation, everything should be logged when debug mode is enabled (i.e. in DEV environment) but I can't see this happening; I only see Doctrine queries, but no JSON.
How can I dump the JSON created by FosElasticaBundle?
Update: mappings
# FOSElasticaBundle
fos_elastica:
clients:
default: { host: %elasticsearch_host%, port: %elasticsearch_port%, logger: false }
indexes:
app:
types:
user:
mappings:
name: ~
surname: ~
persistence:
driver: orm
model: AppBundle\Entity\User
provider: ~
listener: ~
finder: ~
I think you should only set your logger to true instead of false
fos_elastica:
clients:
default:
host: %elasticsearch_host%
port: %elasticsearch_port%
logger: true <---- set true here
...

Resources