2

I have an "article" entity, that have a one to many relation with the entity "rate".

My articles are already indexed. I want to add to index the rate average for the article (calculated with the "rate" entities related to the article), and i don't know how to do this, also the average rate has to be updated if a new rate is created.

for the mapping in config.yml :

indexes:
    piy:
        client: default
        settings:
            index:
                analysis:
                  analyzer:
                    custom_search_analyzer:
                        type: custom
                        tokenizer: standard
                        filter   : [standard, lowercase, asciifolding]
                    custom_index_analyzer:
                        type: custom
                        tokenizer: standard
                        filter   : [standard, lowercase, asciifolding, custom_filter]
                  filter:
                    custom_filter:
                        type: edgeNGram
                        side: front
                        min_gram: 1
                        max_gram: 20
        types:
            article:
                mappings:
                    title : { search_analyzer: custom_search_analyzer, index_analyzer: custom_index_analyzer, type: string }
                    user:
                      type : object
                      properties : 
                        fullName : { search_analyzer: custom_search_analyzer, index_analyzer: custom_index_analyzer, type: string }
                persistence:
                    driver: orm
                    model: Piy\CoreBundle\Entity\Article
                    elastica_to_model_transformer:
                      service: piy.transformers.elastica.article
                    finder: ~
                    provider: ~
                    listener: ~            

and for the rate entity mapping :

/**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="integer", length=1)
     */
    private $value;


    /**
     * @ORM\ManyToOne(targetEntity="Piy\CoreBundle\Entity\User", inversedBy="articleRates")
    */
    public $user; 

    /**
     * @ORM\ManyToOne(targetEntity="Piy\CoreBundle\Entity\Article", inversedBy="rates")
     */
    private $article;
user3328275
  • 53
  • 1
  • 6
  • Could you provide your current mapping in config.yml? Also we need to know the structure of your entities (at least the rate one) – Javad May 14 '14 at 16:11
  • Thanks; Now what fields of your rate entity do you want to be indexed? I need the entity mapping (just the structure) – Javad May 14 '14 at 16:18
  • I want to index the average of the "rate" values related to the article – user3328275 May 14 '14 at 16:19

2 Answers2

1

I found a way to do this, by adding a filter script :

$rateFilter = new \Elastica\Filter\Script("sum=0; foreach( rate : doc['value'].values) { sum = sum + rate }; avg = sum/doc['value'].values.length; avg >= ".$searchRate.";  ");

But now i have an other problem : when i add a new rate on an article, it is not added in the index ...

EDIT : To update the article parent when a rate is added or updated, i have added a listener on postPersist and postUpdate for rate, that launch the postUpdate of the article, and update the index

user3328275
  • 53
  • 1
  • 6
0

What you need is to update the index mapping for the related objects (rate entity) as below

...
    types:
        article:
            mappings:
                title : { search_analyzer: custom_search_analyzer, index_analyzer: custom_index_analyzer, type: string }
                user:
                  type : object
                  properties : 
                    fullName : { search_analyzer: custom_search_analyzer, index_analyzer: custom_index_analyzer, type: string }
                rates:
                   type : object
                   properties :
                      id : ~
                      value: ~

Now it will index the article and the value related to the article (if no values is set to the article it will index the article but no values)

Javad
  • 4,339
  • 3
  • 21
  • 36
  • OK thanks, I have 2 questions : why put the id property ? After thath how can i get the average of all the rate values for the article ? – user3328275 May 14 '14 at 16:32
  • It's optional (I did because they are related base on ID and the result of your query search will be entity object; On the other you be able to do search in reverse; I mean search by Id value and get the related article. Again it's optional) To get the average you can apply the logic to the result of your search, or you can create a custom analyzer which build this logic for you – Javad May 14 '14 at 16:39
  • I have to add the average in my filter form, and filter on that value in my query, how can i do, with a custom analyzer ? – user3328275 May 14 '14 at 17:25
  • @user3328275 I am not sure but when you create a filter by Elastica you might be able to inject your logic base on Elastica CustomFilterScore api (http://elastica.io/api/classes/Elastica.Query.CustomFiltersScore.html#method_addFilterScript) – Javad May 14 '14 at 18:30