Monday 25 November 2019

Azure Search - Improving speed while getting facets only

If you want to get only facets from your search query - for some purposes as preparing filters list - remember to set limit to 0.

For example like this:

var facetResults = searchQuery.Take(0).GetFacets();

.Take(0) translates to $top=0 in Azure Search query. That will return something like this:

{
    "@odata.context": "https://{YOUR-SEARCH-SERVICE}.search.windows.net/indexes('my-index-web-index-99')/$metadata#docs(*)",
    "@odata.count": 857,
    "@search.facets": {
        "contenttype_facet_1": [
            {
                "count": 146,
                "value": "Content Type 1"
            },
            {
                "count": 134,
                "value": "Content Type 2"
            },
            {
                "count": 118,
                "value": "Content Type 3"
            },
        ],
        "topic_facet_1": [
            {
                "count": 176,
                "value": "Topic 1"
            },
            {
                "count": 70,
                "value": "Topic 2"
            },
            {
                "count": 62,
                "value": "Topic 3"
            },
            {
                "count": 52,
                "value": "Topic 4"
            }
        ],
        "subtopic_facet_1": [
            {
                "count": 49,
                "value": "Subtopic 1"
            },
            {
                "count": 32,
                "value": "Subtopic 2"
            }
        ]
    },
    "value": []
}

So only essential statistics data without actual results

Friday 1 November 2019

RenderField processor for tooltip links

A couple of days ago I've got a requirement from my client about inline tooltips functionality. Those tooltips needed to have formatted text so RTE field should be used.


I started with creating repository folder for those tooltips




Template for tooltip item was really simple, just one RTE field



To have a link which will open a tooltip I had to write a pipeline processor which
  • Will read RTE field content
  • Find internal links
  • Check if they point to tooltip item
    • If yes then process link



This pipeline processor must be run after field value is read, so after
Sitecore.Pipelines.RenderField.GetFieldValue, Sitecore.Kernel

Sunday 20 October 2019

Helix Publishing Pipeline - file locks issue on deploy

On my last project when I was implementing Helix Publishing Pipeline I found really bizarre issue. Almost every time I was deploying code by publishing it from Visual Studio, some dlls were locked by w3wp process.

No surprise IIS uses those assemblies but I didn't have such locking problem earlier.

I was digging for hours in the Internet and I found out that IIS uses assembly shadowing. So basically it doesn't use directly dlls from webroot bin, but from its the temp folder.

It can be disabled by this setting

<hostingEnvironment shadowCopyBinAssemblies="false" />

When I set this for test, file locks were all over the place.

Earlier I used Process Explorer and I saw that w3wp locks not only shadowed dlls but as well those from webroot bin, so something was not right there!



More digging eventually gave me information that our issue was self-inflicted: https://stackoverflow.com/a/28019475

In GlassMapperScCustom assemblies were loaded by invoking method
Assembly.LoadFile(assemblyPath) 

which loads exact assemblies and it doesn't take into account shadows.

Instead of that we should always use

Assembly.LoadFrom(assemblyPath) 

which loads shadows as it should be.

That fixed issue with file locks for good!

Tuesday 19 February 2019

Azure Search provider - Results ordering issue

I was implementing Azure Search lately into my last project and I found some strange issue in the provider (we're using Sitecore 9.0.2 rev. 180604). When I wanted to order my search results using Linq like this:

searchQuery.OrderBy(x => x.JobRole).ThenBy(x => x.LastName)

it was translated to:

$orderby=last_name_s,job_role_i

So it looks like it's taking argument of ThenBy as first and OrderBy as the second. Inverting parameters:

searchQuery.OrderBy(x => x.LastName).ThenBy(x => x.JobRole)

gave me desired query:

$orderby=job_role_i,last_name_s

And search result as well were sorted like I wanted.

Azure Search documentation states nothing unusual, but I had to confirm this:


$orderby=[string] (optional)

A list of comma-separated expressions to sort the results by. When calling via POST, this parameter is named orderby instead of $orderby. Each expression can be either a field name or a call to the geo.distance() function. Each expression can be followed by asc to indicate ascending, and desc to indicate descending. The default is ascending order. Ties will be broken by the match scores of documents. If no $orderby is specified, the default sort order is descending by document match score. There is a limit of 32 clauses for $orderby.
https://docs.microsoft.com/en-us/rest/api/searchservice/search-documents#orderbystring-optional

I have raised an issue on Sitecore Helpdesk and guys from support checked and reported the issue. It has a reference number 309333. Current resolution is to invert parameters like I did.