FOSElasticaBundle/Resources/doc/types.md
2014-05-23 23:11:45 +10:00

10 KiB

Type configuration

Handling missing results with FOSElasticaBundle

By default, FOSElasticaBundle will throw an exception if the results returned from Elasticsearch are different from the results it finds from the chosen persistence provider. This may pose problems for a large index where updates do not occur instantly or another process has removed the results from your persistence provider without updating Elasticsearch.

The error you're likely to see is something like: 'Cannot find corresponding Doctrine objects for all Elastica results.'

To solve this issue, each type can be configured to ignore the missing results:

                user:
                    persistence:
                        elastica_to_model_transformer:
                            ignore_missing: true

Dynamic templates

Dynamic templates allow to define mapping templates that will be applied when dynamic introduction of fields / objects happens.

Documentation

fos_elastica:
    indexes:
        site:
            types:
                user:
                    dynamic_templates:
                        my_template_1:
                            match: apples_*
                            mapping:
                                type: float
                        my_template_2:
                            match: *
                            match_mapping_type: string
                            mapping:
                                type: string
                                index: not_analyzed
                    mappings:
                        username: { type: string }

Nested objects in FOSElasticaBundle

Note that object can autodetect properties

fos_elastica:
    indexes:
        website:
            types:
                post:
                    mappings:
                        date: { boost: 5 }
                        title: { boost: 3 }
                        content: ~
                        comments:
                            type: "nested"
                            properties:
                                date: { boost: 5 }
                                content: ~
                        user:
                            type: "object"
                        approver:
                            type: "object"
                            properties:
                                date: { boost: 5 }

Parent fields

fos_elastica:
    indexes:
        website:
            types:
                comment:
                    mappings:
                        date: { boost: 5 }
                        content: ~
                    _parent:
                        type: "post"
                        property: "post"
                        identifier: "id"

The parent field declaration has the following values:

  • type: The parent type.
  • property: The property in the child entity where to look for the parent entity. It may be ignored if is equal to the parent type.
  • identifier: The property in the parent entity which has the parent identifier. Defaults to id.

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.

Date format example

If you want to specify a date format:

                user:
                    mappings:
                        username: { type: string }
                        lastlogin: { type: date, format: basic_date_time }
                        birthday: { type: date, format: "yyyy-MM-dd" }

Custom settings

Any setting can be specified when declaring a type. For example, to enable a custom analyzer, you could write:

    indexes:
        search:
            settings:
                index:
                    analysis:
                        analyzer:
                            my_analyzer:
                                type: custom
                                tokenizer: lowercase
                                filter   : [my_ngram]
                        filter:
                            my_ngram:
                                type: "nGram"
                                min_gram: 3
                                max_gram: 5
            types:
                blog:
                    mappings:
                        title: { boost: 8, analyzer: my_analyzer }

Provider Configuration

Specifying a custom query builder for populating indexes

When populating an index, it may be required to use a different query builder method to define which entities should be queried.

                user:
                    persistence:
                        provider:
                            query_builder_method: createIsActiveQueryBuilder

Populating batch size

By default, ElasticaBundle will index documents by packets of 100. You can change this value in the provider configuration.

                user:
                    persistence:
                        provider:
                            batch_size: 10

Changing the document identifier

By default, ElasticaBundle will use the id field of your entities as the Elasticsearch document identifier. You can change this value in the persistence configuration.

                user:
                    persistence:
                        identifier: searchId

Turning on the persistence backend logger in production

FOSElasticaBundle will turn of your persistence backend's logging configuration by default when Symfony2 is not in debug mode. You can force FOSElasticaBundle to always disable logging by setting debug_logging to false, to leave logging alone by setting it to true, or leave it set to its default value which will mirror %kernel.debug%.

                user:
                    persistence:
                        provider:
                            debug_logging: false

Listener Configuration

Realtime, selective index update

If you use the Doctrine integration, you can let ElasticaBundle update the indexes automatically when an object is added, updated or removed. It uses Doctrine lifecycle events. Declare that you want to update the index in real time:

                user:
                    persistence:
                        driver: orm
                        model: Application\UserBundle\Entity\User
                        listener: ~ # by default, listens to "insert", "update" and "delete"

Now the index is automatically updated each time the state of the bound Doctrine repository changes. No need to repopulate the whole "user" index when a new User is created.

You can also choose to only listen for some of the events:

                    persistence:
                        listener:
                            insert: true
                            update: false
                            delete: true

Propel doesn't support this feature yet.

Checking an entity method for listener

If you use listeners to update your index, you may need to validate your entities before you index them (e.g. only index "public" entities). Typically, you'll want the listener to be consistent with the provider's query criteria. This may be achieved by using the is_indexable_callback config parameter:

                    persistence:
                        listener:
                            is_indexable_callback: "isPublic"

If is_indexable_callback is a string and the entity has a method with the specified name, the listener will only index entities for which the method returns true. Additionally, you may provide a service and method name pair:

                    persistence:
                        listener:
                            is_indexable_callback: [ "%custom_service_id%", "isIndexable" ]

In this case, the callback_class will be the isIndexable() method on the specified service and the object being considered for indexing will be passed as the only argument. This allows you to do more complex validation (e.g. ACL checks).

If you have the Symfony ExpressionLanguage component installed, you can use expressions to evaluate the callback:

                    persistence:
                        listener:
                            is_indexable_callback: "user.isActive() && user.hasRole('ROLE_USER')"

As you might expect, new entities will only be indexed if the callback_class returns true. Additionally, modified entities will be updated or removed from the index depending on whether the callback_class returns true or false, respectively. The delete listener disregards the callback_class.

Propel doesn't support this feature yet.

Flushing Method

FOSElasticaBundle, since 3.0.0 performs its indexing in the postFlush Doctrine event instead of prePersist and preUpdate which means that indexing will only occur when there has been a successful flush. This new default makes more sense but in the instance where you want to perform indexing before the flush is confirmed you may set the immediate option on a type persistence configuration to true.

                    persistence:
                        listener:
                            immediate: true

Logging Errors

By default FOSElasticaBundle will not catch errors thrown by Elastica/ElasticSearch. Configure a logger per listener if you would rather catch and log these.

                    persistence:
                        listener:
                            logger: true

Specifying true will use the default Elastica logger. Alternatively define your own logger service id.