Charles Leek
Charles Leek

Reputation: 1

Kentico Not able to set EDM.GeographyPoint type as filterable n Azure index

GeographyPoint* type as filterable so i can do proximity searches in Azure. When i build the index in Kentico i am using the CustomAzureSearchModule to change the datatype from EDM.String to EDM.GeographyPoint in the DocumentFieldCreator.Instance.CreatingField.After event. The field is defined in kentico page builder search fields as Retrievable,Searchable,Filterable. When the index is built the Azure type is set to EDM.GeographyPoint, but it is not set as filterable. It needs to be filterable in Azure search index else proximity search like $filter=geo.distance(cafegeolocation, geography'POINT(-71.071138 42.300101)') le 300 cannot work and throws Azure error "Invalid expression: 'geolocation2' is not a filterable field. Only filterable fields can be used in filter expressions.\r\nParameter name: $filter"

Here is code:

[assembly: RegisterModule(typeof(CustomAzureSearchModule))]

namespace Nas.KenticoSites.Domain.GlobalEventModules { public class CustomAzureSearchModule : Module { private string nodeguid = "";

    public CustomAzureSearchModule() : base(nameof(CustomAzureSearchModule))
    {
    }

    protected override void OnInit()
    {
        base.OnInit();
        DataMapper.Instance.RegisterMapping(typeof(GeographyPoint), Microsoft.Azure.Search.Models.DataType.GeographyPoint);
        DocumentCreator.Instance.AddingDocumentValue.Execute += AddingValue;

        // Assigns a handler to the CreatingField.After event for Azure Search indexes
        DocumentFieldCreator.Instance.CreatingField.After += CreatingLocationField_After;
    }

    private void CreatingLocationField_After(object sender, CreateFieldEventArgs e)
    {
        if (e.SearchField.FieldName == "GeoLocation2")
        {
            //Change the field type to Edm.GeographyPoint for Azure Search
            e.Field = new Microsoft.Azure.Search.Models.Field("geolocation2", Microsoft.Azure.Search.Models.DataType.GeographyPoint);
        }
    }

    private void AddingValue(object sender, AddDocumentValueEventArgs e)
    {
        if (e.Document.ContainsKey("nodeguid"))
        {
            nodeguid = e.Document["nodeguid"].ToString();
        }

        if (e.AzureName == "geolocation2")
        {
            //Collect nodeGuid and use to get page
            TreeNode page = DocumentHelper.GetDocuments()
                      .WhereEquals("NodeGUID", nodeguid)
                      .OnCurrentSite()
                      .Culture("en-gb")
                      .TopN(1)
                      .FirstOrDefault();

            if (page != null)
            {
                if (page.ClassName == ServicePage.CLASS_NAME) // Check page type is a service only
                {
                    if (page.Children.Count > 0)
                    {
                        foreach (TreeNode location in page.Children.WithAllData.Where(n => n.ClassName == Location.CLASS_NAME).ToList())
                        {
                            Location locationPage = (Location)location;

                            e.Value = GeographyPoint.Create(Convert.ToDouble(locationPage.Latitude), Convert.ToDouble(locationPage.Longitude));
                        }
                    }
                }
            }
        }
    }
}

}

From this example https://devnet.kentico.com/articles/customizing-azure-search-fields

Upvotes: 0

Views: 157

Answers (1)

A. van Hugten
A. van Hugten

Reputation: 823

Can you check in your azure search index that the field is filterable?

enter image description here

If the filterable checkbox is not checked for your 'GeoLocation2' field you could try adding the following code to the 'CreatingLocationField_After' method:

if (e.SearchField.FieldName == "GeoLocation2")
{
    //Change the field type to Edm.GeographyPoint for Azure Search
    e.Field = new Microsoft.Azure.Search.Models.Field("geolocation2", Microsoft.Azure.Search.Models.DataType.GeographyPoint);

    e.Field.IsFilterable = true;
}

This makes the field filterable in azure search and then your query should work.

Upvotes: 1

Related Questions