<p>Looks like a solid plan to do this. And to get the entry models it the same order as you're passing the IDs to your ElementCriteriaModel there's this property: <a href="https://buildwithcraft.com/docs/templating/craft.entries#fixedOrder" rel="nofollow"><code>fixedOrder(true)</code></a>.</p>

<p>Other suggestions could only be to do this with plugin code, but I don't think this would speed up thing noticeably.</p>

CC BY-SA 3.0
2015-04-09T18:42:45.343Z
I think the problem will come in the database load. The number of queries pulling back the categories and tags for all the entries is going to pile up, and as it's per user, it's not something caching would be much help with. I wonder if the category fields could be swapped out for multi-select fields instead to help cut down on that. We could be looking at 1000 article entries so I'm concerned it could grind to a halt.
Russ Back
CC BY-SA 3.0
2015-04-09T18:57:05.067Z
I wonder if we can cache the query results of the initial ALL entries and associated category/tag data query, then we just need to do the looping and do a single call to get the paginated entries in order.
Russ Back
CC BY-SA 3.0
2015-04-09T19:21:59.633Z
Yes that's always the problem with index pages and relational fields. But you could try and cache the entries per user, using the user's ID as the cache key.
carlcs
CC BY-SA 3.0
2015-04-09T19:26:01.160Z
Looks like yii can cache data whereas Craft caches template output so I think we may have a better option there for all users
Russ Back
CC BY-SA 3.0
2015-04-09T21:29:01.043Z
You could also try to reduce the amount of queries with such an approach [Get related entry data without extra queries](http://craftcms.stackexchange.com/q/8988/125).
carlcs
CC BY-SA 3.0
2015-04-09T17:09:30.690Z
2015-04-09T17:09:30.690Z
carlcs
<p>We have been asked to scope a solution for a new site build that we'd like to use Craft for. There is one requirement I'm not sure how we'd approach though.</p>

<p>In Craft terms, we would have an Articles channel that has a number of fields:</p>

<ul>
<li>Employer (relationship to a single Employer channel entry)</li>
<li>Sector (relationship to a single category)</li>
<li>Stage (select field)</li>
<li>Tag (tag field)</li>
</ul>

<p>Then each logged in User would also have the same fields on their profile. I guess it would be easy enough to query the user attributes and pass those to a craft()->entries() call, but the requirements call for a very specific sorting algorithm.</p>

<p>That would work something like this:</p>

<ul>
<li>Article Employer matches User Employer = score of 10</li>
<li>Article Sector matches User Sector = score of 3</li>
<li>Article Stage matches User Stage = score of 4</li>
<li>Article Tags intersect with User Tags = score of 1 x number of matches</li>
</ul>

<p>The result of that score would then be added up and used as a sort dimension against a list all the latest Article entries.</p>

<p>Can anybody suggest a practical (processor efficient) way to achieve this? </p>

<p>My current thinking this:</p>

<ol>
<li>Get all Article entries.</li>
<li>Loop through each Article them and add the calculated score to an array containing the entry ID and the score.</li>
<li>Order the array by score.</li>
<li>Requery all Articles with pagination enabled, passing in a the list of entry IDs in the order defined by the sorted array.</li>
</ol>

<p>Would that work? In particular the last step - can we define entries be sorted by an array of ID numbers?</p>

<p>Any other suggestions would be gladly received.</p>

<entry><search><elementcriteriamodel>
Sorting entries based on an a bespoke algorithm
# Sorting entries based on an a bespoke algorithm

(Asked by: username_0 on 2015-04-09)

We have been asked to scope a solution for a new site build that we'd like to use Craft for. There is one requirement I'm not sure how we'd approach though.

In Craft terms, we would have an Articles channel that has a number of fields:

* Employer (relationship to a single Employer channel entry)
* Sector (relationship to a single category)
* Stage (select field)
* Tag (tag field)

Then each logged in User would also have the same fields on their profile. I guess it would be easy enough to query the user attributes and pass those to a craft()->entries() call, but the requirements call for a very specific sorting algorithm.

That would work something like this:

* Article Employer matches User Employer = score of 10
* Article Sector matches User Sector = score of 3
* Article Stage matches User Stage = score of 4
* Article Tags intersect with User Tags = score of 1 x number of matches

The result of that score would then be added up and used as a sort dimension against a list all the latest Article entries.

Can anybody suggest a practical (processor efficient) way to achieve this?

My current thinking this:

1. Get all Article entries.
2. Loop through each Article them and add the calculated score to an array containing the entry ID and the score.
3. Order the array by score.
4. Requery all Articles with pagination enabled, passing in a the list of entry IDs in the order defined by the sorted array.

Would that work? In particular the last step - can we define entries be sorted by an array of ID numbers?

Any other suggestions would be gladly received.

**Tags:** entry, search, elementcriteriamodel


---

## 1 answers

### Answer by username_1 on 2015-04-09. Score: 1 | Accepted answer

Looks like a solid plan to do this. And to get the entry models it the same order as you're passing the IDs to your ElementCriteriaModel there's this property: [`fixedOrder(true)`](https://buildwithcraft.com/docs/templating/craft.entries#fixedOrder).

Other suggestions could only be to do this with plugin code, but I don't think this would speed up thing noticeably.

> **Comments:**
> **username_0**: I think the problem will come in the database load. The number of queries pulling back the categories and tags for all the entries is going to pile up, and as it's per user, it's not something caching would be much help with. I wonder if the category fields could be swapped out for multi-select fields instead to help cut down on that. We could be looking at 1000 article entries so I'm concerned it could grind to a halt.  
> **username_0**: I wonder if we can cache the query results of the initial ALL entries and associated category/tag data query, then we just need to do the looping and do a single call to get the paginated entries in order.  
> **username_1**: Yes that's always the problem with index pages and relational fields. But you could try and cache the entries per user, using the user's ID as the cache key.  
> **username_0**: Looks like yii can cache data whereas Craft caches template output so I think we may have a better option there for all users  
> **username_1**: You could also try to reduce the amount of queries with such an approach [Get related entry data without extra queries](http://craftcms.stackexchange.com/q/8988/125).  

---

