1

I need to tune performance on a Craft 2 build. We are quite new to Craft CMS, so please bear with me if the question sounds silly.

We need to render a page that needs to display information from 4 sections, A->B->C->D, with the latter having a reference to the former, i.e. B has a field linking to A, C has a field linking to B, and D has a field linking to C. The page needs to list A entries with information gathered from B, C, D. We ended up using relatedTo in three foreach lookup until D, which turned out to be super inefficient. I managed to find out that using eager-loading of elements can greatly reduce the number of queries, which in my case, I've got 400+ queries down to about 40. The page load time is roughly 2s (from previous 30+ seconds!).

However, I think there might be an even better way to query the db. Currently, I am querying all elements of A, taking this array to query all related entries of B, which again is taken to query all entries of C. On querying entries of C, this is where eager-loading happens. The query on C section looks like this:

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->section = 'Section A';
$criteria->with = array(
    'b',
    'b.field_a',
    'd',
);
$criteria->relatedTo = array(
    'targetElement' => $obj,
    'field' => 'field_d'
);

I am wondering if there's a way to query related entries based on a field from an ancestor, like

$criteria->relatedTo = array(
    'targetElement' => $obj,
    'field' => 'field_d.c.b.a.field'
);

That would save me from querying B and C entries.

Many thanks!

  • It sounds like D is a child of C which is a child of B which is a child of A. Is it possible to use a structure for this or do all of these sections need to be on the same level? – Cavell Blood Aug 1 '17 at 10:45
  • 1
    I am not sure about structures to be honest. As far as I can see, the main difference between channels and structures is the ordering ability. In my case, it's simply that multiple types of entries chain one another. Anyway, I have worked around it by changing the relationship from manyToOne to oneToMany, i.e, put the relation field on the "one" side, so I can use with criteria. – user6848 Aug 1 '17 at 11:47
  • Glad you were able to figure it out! Post the code here as the answer if you get a chance. – Cavell Blood Aug 1 '17 at 15:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.