Azure 搜索索引器无法检索从 DocumentDB 中的文档归档的 GeographyPoint
Azure Search Indexer cannot retrieve a GeographyPoint filed from a document in DocumentDB
我在尝试索引存储在 DocumentDb 集合中的文档时遇到问题。
索引器的数据源是使用自定义 SQL 定义的,用于检索已更改的文档。我要索引的文档有一个名为 LocationGP
的 属性,它是一个 Microsoft.Spatial.GeographyPoint,并映射到具有相同名称并定义为 DataType.GeographyPoint
[ 的索引字段=14=]
我在尝试创建索引器时遇到的错误是:
列 'LocationGP' 的类型为 JObject,与索引中 Edm.GeographyPoint 类型的字段不兼容
有什么想法吗?
这是数据源的定义:
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")
};
这是文档:
[{
"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
}]
问题是 Edm.GeographyPoint
的格式与 Microsoft.Spatial.GeographyPoint
不同。
为了让它工作,我刚刚创建了一个名为 EdmGeograpyPoint
的 class,如下所示:
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; }
}
然后我将 LocationGP 属性 的类型替换为 EdmLocation。
也许有更好的解决方案,但有关此主题的文档令人困惑:
https://azure.microsoft.com/en-us/documentation/articles/search-howto-dotnet-sdk/
这里有两个关于 Azure 搜索的文档,解释了可接受的地理实例类型:
- https://msdn.microsoft.com/en-us/library/azure/dn798938.aspx
- https://msdn.microsoft.com/en-us/library/azure/dn946880.aspx?f=255&MSPPError=-2147217396
基本上需要GeoJSON "Point"类型的格式。
我回答的有点晚,但我希望有人能从中受益。
在我看来,处理这个问题最简洁的方法是继续使用 'built-in' classes/framework,而不必创建自己的复杂类型。
我解决这个问题的方法是使用利用 Microsoft.Azure.Search.Serialization 命名空间的 JsonConverter。此命名空间具有 GeographyPoint 扩展名,即 'ReadGeoJsonPoint()' 和 'WriteJson()' 扩展名。
我做了以下事情:
// 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))]
我在尝试索引存储在 DocumentDb 集合中的文档时遇到问题。
索引器的数据源是使用自定义 SQL 定义的,用于检索已更改的文档。我要索引的文档有一个名为 LocationGP
的 属性,它是一个 Microsoft.Spatial.GeographyPoint,并映射到具有相同名称并定义为 DataType.GeographyPoint
[ 的索引字段=14=]
我在尝试创建索引器时遇到的错误是:
列 'LocationGP' 的类型为 JObject,与索引中 Edm.GeographyPoint 类型的字段不兼容
有什么想法吗?
这是数据源的定义:
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")
};
这是文档:
[{
"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
}]
问题是 Edm.GeographyPoint
的格式与 Microsoft.Spatial.GeographyPoint
不同。
为了让它工作,我刚刚创建了一个名为 EdmGeograpyPoint
的 class,如下所示:
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; }
}
然后我将 LocationGP 属性 的类型替换为 EdmLocation。
也许有更好的解决方案,但有关此主题的文档令人困惑: https://azure.microsoft.com/en-us/documentation/articles/search-howto-dotnet-sdk/
这里有两个关于 Azure 搜索的文档,解释了可接受的地理实例类型:
- https://msdn.microsoft.com/en-us/library/azure/dn798938.aspx
- https://msdn.microsoft.com/en-us/library/azure/dn946880.aspx?f=255&MSPPError=-2147217396
基本上需要GeoJSON "Point"类型的格式。
我回答的有点晚,但我希望有人能从中受益。
在我看来,处理这个问题最简洁的方法是继续使用 'built-in' classes/framework,而不必创建自己的复杂类型。
我解决这个问题的方法是使用利用 Microsoft.Azure.Search.Serialization 命名空间的 JsonConverter。此命名空间具有 GeographyPoint 扩展名,即 'ReadGeoJsonPoint()' 和 'WriteJson()' 扩展名。
我做了以下事情:
// 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))]