Friday, June 2, 2017

Deeper dive in to Coveo Advanced Expressions

In our implementation we stumbled upon looking at what Coveo calls 'aq' bunch of times.  It is simply because of complexity involved on our implementation where we had to bend Coveo a little to achieve what the business needs are.

First up, let us first understand a little what is aq, dq and cq per Coveo.  They have beautiful documentation that iterates what these are.
https://developers.coveo.com/display/public/SearchREST/Query+Parameters

So, every time a query is fired by Coveo rendering because of coveo components you have on the page.   All these query parameters based on what is applicable is generated by Coveo, you can see this on Network tab in your browser when you take a look at Request headers and parameters.  If what coveo generates satisfies your business goals, you are good to call it a day.  But, what if it is not enough, you have to then modify and tweak to achieve what is needed.

When it comes to modifying the aq generated gracefully it becomes a challenge specifically if you are having issues with what Coveo does inherently while computing 'aq' for a rendering/request
One such case happened recently, where we needed a disjunction to be applied at a specific piece of generated 'aq'.  We obviously could not get away with disjunctive expressions, I talked about this in my previous blog if you are curious.

https://deepthikatta.blogspot.com/2016/11/coveo-facet-slider-across-two-fields.html


The reason why this approach would not work in this case is because the way disjunctive expression works and is interpreted by Coveo in final query is aq OR dq which means in result set you will find all items that match your filters appended by Coveo in aq OR that match your expression that you added on dq.

But, what if you want this disjunction to applied only on a particular facet or custom advanced expression.  How can we do this? is it possible?

Like always, everything is possible. :)  In our case, it is little more complex because we also did not want what Coveo typically injects as a piece of aq on a Facet Slider for example because we would fall in to same problem which we began to solve if we don't do this.   So, to achieve this, we did two steps.

1.  OR where you need - In event called buildingQuery, access the args and append the advanced expression that you need including a specific OR condition you care about.  Some thing like
 Coveo.$('#@Model.Id')
        .on("buildingQuery", function(e, args) {
            let mySlider = Coveo.$('#mySlider')
              if (mySlider != undefined) {
              let optionsOfComponent = mySlider.coveo().getSliderBoundaryForQuery()
               if (optionsOfComponent != undefined && optionsOfComponent[0] != undefined && optionsOfComponent[1] != undefined) {
                let fieldOneQuery= '@(Model.ToCoveoFieldName("field one")) >=' + optionsOfComponent[0] + ' AND @(Model.ToCoveoFieldName("field one")) <=' + optionsOfComponent[1]
                let fieldtwoQuery= '@(Model.ToCoveoFieldName("field two")) >=' + optionsOfComponent[0] + ' AND @(Model.ToCoveoFieldName("field two")) <=' + optionsOfComponent[1]
                args.queryBuilder.advancedExpression.add('((' + fieldOneQuery+ ') OR (' + fieldtwoQuery+ '))')
              }
      }

         })
2. Remove the advanced expression added by Coveo -  Reverse engineered the string that Coveo would append on the facet slider per configuration and removed it using helper provided under Expression Builder.
https://developers.coveo.com/display/public/JsSearch/ExpressionBuilder

Some thing like -
 .on("doneBuildingQuery", function(e, args)  {
   //reverse engineer the value you would like to remove and ensure you have proper checks on coveo      components or facets before you access the values
    let  expressionToRemove  = '@(Model.ToCoveoFieldName("your slider         field"))=='+optionsOfComponent[0]+'..'+optionsOfComponent[1]
    args.queryBuilder.advancedExpression.remove(expressionToRemove)
   })

That is it, we got what we needed when took a peek at Network tab and request parameters and the results matched to business goal.   One less thing to worry about.  We are launching this thing soon, totally psyched!


No comments :

Post a Comment