FOSElasticaBundle NumberFormatException error on populate - symfony

I use FOSElasticaBundle in my Symfony 2 project. Since today reindexing is resulting in the below error:
index: /app/hotel/1 caused MapperParsingException[failed to parse
[priceFrom]]; nested: NumberFormatException[For input string:
"410.00"];
In my doctrine orm yml the priceFrom field is defined as followed:
priceFrom:
type: decimal
nullable: true
precision: 7
scale: 2
comment: ''
column: price_from
My fos_elastica config looks like this (config.yml):
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
app:
types:
hotel:
mappings:
id: ~
active: ~
priceFrom: { type: integer }
persistence:
driver: orm
model: XXX\XXXBundle\Entity\Hotel
provider: ~
listener:
immediate: ~
finder: ~
The command I use to reindex: php app/console fos:elastica:populate
The above setup has worked until now. I hope someone can point my to the good direction to solve this problem.
Versions:
ruflin/elastica (2.1.0)
friendsofsymfony/elastica-bundle (v3.1.5)
symfony/symfony (v2.6.11)
PS: No other entities in my project are using a priceFrom field.

In mappings, you define PriceFrom as integer but then you pass a decimal.
I haven't tested it but it definitely seems the major candidate as the culprit.

Francesco Abeni is right with answer. If you are already pushed something in ES as integer (or ES defined it as integer) it will generate exception when you will try to save decimal data here.
I always explicitly specify type in mapping like:
id: {"type" : "integer"}
shop_id: {"type" : "integer"}
source: {"type" : "string", "index" : "not_analyzed"}
There I see two ways to solve problem.
index alias and index merge
specify type in mapping; kill index; populate in again
I used second variant on a dev :)

Related

How to do FOSElasticaBundle bulk index?

It seems that the default doctrine listener used by FOSElasticaBundle does not support bulk index by default. I have an application where I want to add support for more complex search queries through ElasticSearch. The search engine only will perform queries through one unique entity Post. When I create, edit or delete there is not any problem, the index in elasticsearch is updated automatically through the listener. My problem comes when I want to do bulk updates to hide or show more than one post at once, the listener is not receiving the signal to make the bulk index update in elasticsearch.
I am new to FOSElasticSearch so I do not know if I am missing something. I am using FOSElasticaBundle 6, Symfony 5.2 and ElasticSearch 7
Here you can find my fos_elastica.yaml
fos_elastica:
messenger: ~
clients:
default: { host: 127.0.0.1, port: 9200 }
indexes:
product:
settings:
index:
analysis:
analyzer:
my_analyzer:
type: snowball
language: English
persistence:
# the driver can be orm, mongodb or phpcr
driver: orm
model: App\Entity\Post
listener: { enabled: true }
provider: ~
finder: ~
elastica_to_model_transformer:
ignore_missing: true
properties:
title: { boost: 10, analyzer: my_analyzer }
tags: { boost: 8, analyzer: my_analyzer }
description: { boost: 6, analyzer: my_analyzer }
ispublished: { type: integer}
And here you can find the way I am updating more than once entity element at once in PostRepository (the function is to update all post from one unique author, it is just an example):
public function bulkUpdate($ispublished, $authorid){
return $this->createQueryBuilder('p')
->update()
->set('p.ispublished', $ispublished)
->andWhere('p.authorid = :id')
->setParameter('id', $authorid)
->getQuery()
->execute();
}
Also I found that I could disable default listener, dispatch messages for each create, update or delete action through symfony/messenger and consume them async in the background. I guess that I should create my own handler and dispatch specific messages (although I could not find an example about this in the doc) in each modifying action, although at the end I also have the same problem, as I do not know how to send a bulk index update/delete action
In the other hand I was thinking in executing all time a background script in python to check what rows were modified in mysql database and update those index with the script directly through ElasticSearch Api
I do not think that I will need to update more than 1k posts at once, so I would like to keep using the default listener to update posts automatically and avoid gaps between that an entity is modified and the index is updated in ElasticSearch. I just need to find the best way to update indexes in bulk as I have everything else already implemented and working
Sorry for all the text but I wanted to give all details about what I need to do

Elasticsearch with symfony - Error populate command softdeletable entity

I use the symfony bundle Foselasticabundle and i am facing a problem.
I have an entity (B) which can be deleted via gedmo softdeleteable.
I created the mapping, via the YAML file, and when I execute the following command fos:elastica:populate i get an error.
Entity of type 'App\Entity\B' for IDs id(XX) was not found
In fact, value was previously deleted in my database...
I would have liked him to insert an empty value in the field
Do you have a solution?
Thank you for your answers
fos_elastica.yaml
clients:
default: { url: '%env(ELASTICSEARCH_URL)%/' }
indexes:
app:
types:
A:
properties:
id: ~
name: ~
B:
type: object
id: ~
persistence:
driver: orm
model: App\Entity\A

Having problems setting up AWS S3/Cloudfront with Symfony and LiipImagineBundle

I'm trying to set up AWS S3/Cloudfront to work with liipimaginebundle in Symfony, but I really have no idea what I'm doing.
So far I have tried the following documented here http://symfony.com/doc/current/bundles/LiipImagineBundle/cache-resolver/aws_s3.html:
Installed aws-sdk-php:
"require": {
"aws/aws-sdk-php": "^3.28",
}
Set up my parameters (with the correct values not this dummy data):
amazon.s3.key: "your-aws-key"
amazon.s3.secret: "your-aws-secret"
amazon.s3.bucket: "your-bucket.example.com"
amazon.s3.region: "your-bucket-region"
Set up a resolver (although I'm not sure what that even means).
"%amazon.s3.cache_bucket%" is in the documentation but the parameter doesn't exist so I used "%amazon.s3.bucket%" instead:
liip_imagine:
cache: profile_photos
resolvers:
profile_photos:
aws_s3:
client_config:
credentials:
key: "%amazon.s3.key%"
secret: "%amazon.s3.secret%"
region: "%amazon.s3.region%"
bucket: "%amazon.s3.bucket%"
get_options:
Scheme: https
put_options:
CacheControl: "max-age=86400"
Added these lines to create the services:
services:
acme.amazon_s3:
class: Aws\S3\S3Client
factory: Aws\S3\S3Client
arguments:
-
credentials: { key: "%amazon.s3.key%", secret: "%amazon.s3.secret%" }
region: "%amazon.s3.region%"
acme.imagine.cache.resolver.amazon_s3:
class: Liip\ImagineBundle\Imagine\Cache\Resolver\AwsS3Resolver
arguments:
- "#acme.amazon_s3"
- "%amazon.s3.bucket%"
tags:
- { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" }
I'm currently getting this error when I run php bin/console server:run:
PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\UndefinedFunctionException: Attempted to call function "S3Client" from namespace "Aws\S3". in /var/www/swing-polls/var/cache/dev/appDevDebugProjectContainer.php:360
I've tried half a dozen other configs/tutorials to no avail. If someone can point me in the right direction I'd be incredibly grateful.
Using the code provided at Simple S3 Symfony Service with a few tweaks, I've been able to get my images to upload to my s3 bucket, but I just don't know how to get liipimaginebundle work with them.
In vendor/liip/imagine-bundle/DependencyInjection/Compiler/ResolversCompilerPass.php you can see the CompilerPass is getting the value from "resolver" attribute of the tag and is using it to create a Reference object. This means the resolver should contain the id of a service.
Try replacing
tags:
- { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" }
with
tags:
- { name: "liip_imagine.cache.resolver", resolver: "acme.amazon_s3" }

How to get groups working for JMSSerializerBundle and FOSRestBundle?

I am trying to set up different groups to achieve different types of serialization of my entities depending on the context.
My config looks like this:
My\FooBundle\Entity\Asset:
exclusion_policy: ALL
access_type: public_method
properties:
id:
access_type: property
expose: true
groups: [fnord]
name:
expose: true
path:
expose: true
isInQuarantine:
expose: true
groups: [baz]
I expect that the group having properties should not be exposed unless the group is set.
I am trying to set the group in my controller via:
$view->setSerializationContext(SerializationContext::create()->setGroups(array('fnord')));
Yet there is no effect on what is exposed and what isn't. Even if I do not try to change the SerializationContext, the groups options seems to be always ignored.
I know that my config is working because I can toggle the properties via the expose flag.
Yet what am I doing wrong here?
I know this question is a bit old, but it may help others.
I encountered a similar issue.
This was because I had in my controler (that extends FOSRestControler) a method with multiple calls to
$this->getView()
You have to notice that this method creates a new View object.
That means, if you call multiple getView methods, the context get reset.
Have a look at the following code that worked for my app :
use FOS\RestBundle\Controller\FOSRestController as Controller;
class RestController extends Controller
{
public function getUserAction($username)
{
$view = $this->view();
$view->setSerializationContext(SerializationContext::create()->setGroups(array('Product')));
$user = $this->getDoctrine()->getManager()->getRepository('VendorUserBundle:User')->findOneByUsername($username);
if(!is_object($user))
{
throw $this->createNotFoundException();
}
$view->setData($user);
return $view;
}
}
In Model.User.yml file :
FOS\UserBundle\Model\User:
exclusion_policy: ALL
properties:
username:
expose: true
groups: [fnord]
email:
expose: true
groups: [Product]
enabled:
expose: true
groups: [Product]
roles:
expose: true
groups: [Product]
Gives the following output :
{"email":"guiguiboy#xxx.com","enabled":true,"roles":["ROLE_XXX"]}
I didn't have any cache related problems (dev env used).

Namespace doesn't contain mapped entities in Symfony 2

I've created a new entity in src/Andrei/StatisticsBundle/Entity/Attribute/Value/ButtonVarchar.php. Here is the code for this class:
<?php
namespace Andrei\StatisticsBundle\Entity\Attribute\Value;
class ButtonVarchar
{
protected $value;
}
and in src/Andrei/StatisticsBundle/Resources/config/doctrine/ButtonVarchar.yml I defined the following mapping information:
Andrei\StatisticsBundle\Entity\Attribute\Value\ButtonVarchar:
type: entity
table: button_attribute_value_varchar
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
value:
type: string
length: 255
manyToOne:
button:
targetEntity: Button
inversedBy: attributeValues
joinColumn:
name: button_id
referencedColumnName: id
For some reason when I run php app/console doctrine:generate:entities I get the following error:
[RuntimeException] Namespace "Andrei\StatisticsBundle\Entity\Attribute\Value" does not contain any mapped entities.
I can't understand why is this happening. Can someone point me to the right direction? Thank you.
Did you add your StatisticsBundle to Doctrine config?
eg:
doctrine:
orm:
auto_mapping: true
mappings:
AndreiStatisticsBundle: ~
You can see mapping problem in the following link:
https://github.com/symfony/symfony/pull/675
It seems that your entities are separated into fine grained packages. In that case you need to specify fully qualified namespace in order for it to work.
targetEntity: Fully\Qualified\Namespace\To\Button
It may also help.
This works:
MyUniqBundle:Entity
This doesn't work:
MyUniqBundle/Entity

Resources