Azure Search Indexer cannot retrieve a GeographyPoint filed from a document in DocumentDB

偶尔善良 提交于 2021-02-10 05:01:47

问题


I'm having an issue while trying to index a document stored in a DocumentDb collection.

The datasource of the indexer was defined with a custom SQL to retrieve the changed documents. The document I want to index has a property called LocationGP which is a Microsoft.Spatial.GeographyPoint, and is mapped to a field of the index with the same name and defined as DataType.GeographyPoint

The error I get when trying to create the indexer is:

Column 'LocationGP' is of type JObject that is not compatible with the field of type Edm.GeographyPoint in the index

Any ideas?

This is the definition of the DataSource:

  return new DataSource()
                {
                    Name = "opportunities-datasource",
                    Container = new DataContainer()
                    {
                        Name = "Companies",
                        Query = @"SELECT    o.id,
                                            o.CompanyName,
                                            o.LocationGP,
                                            o.Location.CityName AS LocationCity,
                                            o.Location.StateName AS LocationState,
                                            o.Location.CountryName AS LocationCountry,
                                            o._ts
                                FROM Companies o WHERE o.DocType = 1 AND o._ts > @HighWaterMark"
                    },
                    Type = "documentdb",
                    Credentials = new DataSourceCredentials()
                    {
                        ConnectionString = String.Format("AccountEndpoint={0};AccountKey={1};Database=CompaniesDb", DocumentDbEndpointUri, DocumentDbPrimaryKey)
                    },
                    DataChangeDetectionPolicy = new HighWaterMarkChangeDetectionPolicy("_ts"),
                    DataDeletionDetectionPolicy = new SoftDeleteColumnDeletionDetectionPolicy("Status", "2")
                };

This is the document:

[{
    "id": "088e1e97-6d59-40ad-a9be-620fdc7938c7",
    "CompanyName": "Neptune",
    "LocationGP": {
      "Latitude": 39.8010482788086,
      "Longitude": -89.6436004638672,
      "IsEmpty": false,
      "Z": null,
      "M": null,
      "CoordinateSystem": {
        "EpsgId": 4326,
        "Id": "4326",
        "Name": "WGS84"
      }
    },
    "Location": {
      "CityName": "Springfield",
      "CountryName": "US",
      "StateName": "IL"
    },
    "Status": 1,
    "DocType": 1,
    "Timestamp": "2016-08-19T16:08:46.0481948Z",
    "_ts": 1471622922
  }]

回答1:


Here are two more documents on Azure Search that explains what type of geography instances are accepted:

  • https://msdn.microsoft.com/en-us/library/azure/dn798938.aspx
  • https://msdn.microsoft.com/en-us/library/azure/dn946880.aspx?f=255&MSPPError=-2147217396

Basically it needs to be in GeoJSON "Point" type format.




回答2:


The problem was that Edm.GeographyPoint has a different format than Microsoft.Spatial.GeographyPoint.

To make it work I just created a class called EdmGeograpyPoint like this:

public class EdmGeographyPoint
{
    public EdmGeographyPoint(double longitude, double latitude)
    {
        coordinates = new double[] { longitude, latitude };
        type = "Point";
    }

    public string type { get; private set; }
    public double[] coordinates { get; private set; }
}

Then I replaced the type of the LocationGP property to EdmLocation.

Maybe there is a better solution, but documentation is confusing around this topic: https://azure.microsoft.com/en-us/documentation/articles/search-howto-dotnet-sdk/




回答3:


I am a bit late with this answer, but I hope someone will benefit from it.

In my opinion, the cleanest way to deal with this is to continue using the 'built-in' classes/framework without having to create your own complex type.

The way I solved this was to use a JsonConverter that harnessed the Microsoft.Azure.Search.Serialization namespace. This namespace has the GeographyPoint extensions i.e. 'ReadGeoJsonPoint()' and 'WriteJson()' extensions.

I did the following:

 //    1. Create a JsonConverter
   using Microsoft.Azure.Search.Serialization;
   public class GeographyPointJsonConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(GeographyPoint);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return reader.ReadGeoJsonPoint();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            writer.WriteGeoJsonPoint(value as GeographyPoint);
        }
    }

    //2. Added the convert to the property I was looking to index
    [JsonConverter(typeof(GeographyPointJsonConverter))]


来源:https://stackoverflow.com/questions/39043968/azure-search-indexer-cannot-retrieve-a-geographypoint-filed-from-a-document-in-d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!