0

I'm using elasticsearch in symfony2 the FOSElasticaBundle and was wondering what is standard practice for retrieving objects after searching.

Say I have mapped all fields of my doctrine object so they are all stored, more importantly returned, in elasticsearch. Now, after I search and have an Elastica\ResultSet. The default finder in the FOSElasticaBundle will ignore the data in the ResultSet and query the sql db to get Doctrine objects (which are then passed to the template to be drawn).

  1. I was wondering if this was commonly done (two queries to different datastores) as it seems a bit wasteful. Or do people create Doctrine objects manually from the ResultSet.

  2. If you do create the objects manually, it could be possible that elasticsearch's data is outdated. Now this is not a problem for viewing, but wouldn't creating doctrine objects from outdated data possibly cause this old data to get persisted (if some part of the code flushes; we had this issue with symfony 1.4 and doctrine 1.2).

Thanks!


Update

After reading a bit more, I have 2 ideas (except for the easy but wasteful extra sql query method):

  1. Create a custom ElasticaToModelTransformer, and also detach the entities from doctrines entity manager, ensuring they do not get persisted accidentally. Reading a bit more from the doctrine docs it seems like I might not actually need to do this. Are unserialized objects attached to the entity manager?

  2. Create a normalized php array representing the object and have all the templates dray from this array rather than the doctrine object. As talked about on the symfony serializer component docs this is a state between the object as an instance of an entity, and the object serialized into some format (JSON, xml), and so this array could be created by either an elasticsearch result or a doctrine object and the template does not need to care.

    This approach does mean you cannot call methods to retrieve related objects from the template if needed, you are limited to the info in the array.

Community
  • 1
  • 1
ramseykhalaf
  • 3,371
  • 2
  • 17
  • 16

2 Answers2

0

You got it right in the question actually.

When working with an ORM, if you create obsolete objects from ElasticSearch and then persist them, Doctrine will save your old values to the primary Data Store. And that's bad.

Here is the two solutions with pro's and con's:

  1. Asking ES to return only the document ID's (via "fields") and then fetching them from Doctrine is a great way to deal with it: The overhead is low, and you have the benefit or real Doctrine objects (can be edited, are up to date, share the same template as others...). That's what ElasticaBundle do. You only have to index the fields needed for search (smaller index).

  2. Using the ES Document directly is trickier: you do not have to map all the fields (you get the Source, which is your indexation doc untouched) but you have to adapt your views, you will not be able to call custom getters, and more globally you will not be able to perform any business logic on the Document. Also, you have to index EVERY field you want on display, not only the one you search on (bigger index).

Damien
  • 5,872
  • 2
  • 29
  • 35
  • I guess I was hoping to create an object (I think in a proxy state) from the elasticsearch document without going to the sql db. Most of the time this object would contain enough data for the template to draw without further queries. I'm more worried about the objects being persisted. I guess my question is: **Is there anyway to create doctrine objects and ENSURE they never get persisted to the sql db?** – ramseykhalaf Aug 23 '13 at 08:57
0

If anybody was looking for an answer, here is sth that might be useful: FOSElasticaBundle and Doctrine Hydration

Community
  • 1
  • 1
pkoltermann
  • 113
  • 1
  • 6