Тип
GeographyPoint * фильтруемый, поэтому я могу выполнять поиск по близости в Azure. Когда я создаю индекс в Kentico, я использую CustomAzureSearchModule , чтобы изменить тип данных с EDM.String на EDM.GeographyPoint в событии DocumentFieldCreator.Instance.CreatingField.After . Поле определяется в полях поиска конструктора страниц kentico как Retrievable, Searchable, Filterable. При построении индекса тип Azure устанавливается в EDM.GeographyPoint, но не устанавливается как фильтруемый. Он должен быть отфильтрован в Azure индексе поиска, иначе поиск близости, например $ filter = geo.distance (cafegeolocation, geography'POINT (-71.071138 42.300101) ') le 300 не может работать и выдает Azure ошибку «Недопустимое выражение: 'geolocation2' не является фильтруемым полем. В выражениях фильтра можно использовать только фильтруемые поля. \ R \ n Имя параметра: $ filter»
Вот код:
[сборка: RegisterModule (typeof (CustomAzureSearchModule))]
пространство имен Nas.KenticoSites.Domain.GlobalEventModules {publi c 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));
}
}
}
}
}
}
}
}
Из этого примера https://devnet.kentico.com/articles/customizing-azure-search-fields