4

So I have created a combined search for products and entries using the new Craft 2.5 search score. It's working well, but...I was hoping to be able to do this without a plugin if possible ... but it doesn't seem immediately possible to do unless I am missing something.

If anyone knows a way, it would be much appreciated. In the meantime I'll post the solution I have come up with as an answer below.

4

To get this working I submitted a patch to 'SortByField' - https://github.com/dannynimmo/craftcms-sortbyfield - to get this plugin to work with Commerce products - and I now do this:

    {% set product_results = craft.commerce.products.search(query).order('score') %}  
    {% set article_results = craft.entries.search(query).order('score') %}
    {% set all_results = [] %}

    {% if product_results|length %}
        {% set all_results = all_results|merge(product_results) %}
    {% endif %}
    {% if article_results|length %}
        {% set all_results = all_results|merge(article_results) %}
    {% endif %}

    {% if all_results|length %}
        {% set all_results = all_results|sortByField('searchScore', 'desc') %}
    etc.

Which is working well and the combined results make sense to me.

I am just wondering if their is a better/recommended and ideally plugin free way of doing this - i.e. sorting the combined result set by score?

  • Another plugin solution, but it should work without a patch: Supersort (which I hope gets included into Craft core at some point. It basically just brings PHPs sort functions to Twig!). – carlcs Nov 18 '15 at 10:11
  • @carlcs - It doesn't seem obvious that Supersort can do a sort specifically on the searchScore field though? I did check it out intially but maybe missed something? – Jeremy Daalder Nov 19 '15 at 1:08
  • Jeremy, Supersort's sortAs methods work like so: the second param can be a Twig "microtemplate", passed in as a string. Each row is available as a object named object, so {{ object.searchScore }} should return what you need and is then used as the value to sort by. – carlcs Nov 19 '15 at 8:14
  • 1
    Thanks Carl, very helpful once again! I accepted my own answer here because in terms of the question it's the best method I can find, and with your recipe for self pagination it should work well. Thanks for your input! – Jeremy Daalder Nov 19 '15 at 22:04
1

You could do all of this in PHP. Build your criteria models, merge the results and sort them with usort.

  • Yep for sure, PHP seems the way to go here currently. – Jeremy Daalder Nov 18 '15 at 22:01
  • The problem beyond a PHP solution, though, is that one can't then do things like paginate the result set. As pagination relies on an ElementCriteriaModel rather than an array of found results. I prefer my solution that uses less custom PHP and an existing, more tested plugin to be honest. In terms of building my own PHP, I'd certianly do it if I could work out a way to return an ECM that could cope with both products and entries, but I don't think this is possible. In all, I still think my solution above is the best currently. Might just have to live without pagination for now... – Jeremy Daalder Nov 19 '15 at 1:11
  • I think you are right, and you probably can't build a criteria model including mulitple element types, unfortunatelly this is also the case for both plugin solutions we listed in the other answer. But what you could do is to build your own pagination logic, I also had to do this for a project (I even had a criteria model, but there was a bug with the paginate tag!). Will post the code below. – carlcs Nov 19 '15 at 8:19
  • Posted it as a new question: Paginate entries when I do not have a criteria model? – carlcs Nov 19 '15 at 8:37

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.