Azure / azure-cosmos-dotnet-v2

Contains samples and utilities relating to the Azure Cosmos DB .NET SDK
MIT License
578 stars 836 forks source link

JsonProperty breaks geospatial linq #207

Open morganabel opened 7 years ago

morganabel commented 7 years ago

I wrote a test that basically deletes a collection, recreates it and then inserts 5 entities with the following schema:

internal class TestGeoEntity : TestDocDbEntity, IGeoDocDbEntity
        {
            [JsonProperty("testString")]
            public string TestString { get; set; }

            [JsonProperty("id")]
            public virtual string Id { get; set; }

            [JsonProperty("partitionKey")]
            public string PartitionKey { get; set; }

            public Point GeoLocation { get; set; }
        }

this works completely fine and returns the expected results. But if I add a JsonProperty to GeoLocation like below:

internal class TestGeoEntity : TestDocDbEntity, IGeoDocDbEntity
        {
            [JsonProperty("testString")]
            public string TestString { get; set; }

            [JsonProperty("id")]
            public virtual string Id { get; set; }

            [JsonProperty("partitionKey")]
            public string PartitionKey { get; set; }

            [JsonProperty("geoLocation")] 
            public Point GeoLocation { get; set; }
        }

No results are found (even though collection is recreated and the values in db are formatted properly, so that is not the problem). This is running in the emulator, so that might be the problem.

This is the code I am using to query:

Expression<Func<T, bool>> geoWhere = t => t.GeoLocation.Distance(point) <= rangeInMeters;
var feedOptions = _defaultFeedOptions;

var query = Client.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(_database.Id, collectionId),
                            feedOptions)
                        .Where(whereExpression)
                        .Take(take);

var results = await query.AsDocumentQuery().ExecuteNextAsync<T>();
zfang commented 7 years ago

Could you provide the following:

  1. query.ToString()
  2. Actual JSON document that's in the collection
morganabel commented 7 years ago

Here is an example JSON document in the collection:

{
    "geoLocation": {
        "type": "Point",
        "coordinates": [
            -111.9,
            33.4
        ]
    },
    "testString": "blah1",
    "id": "testgeo1",
    "partitionKey": "9tbq",
    "_rid": "aDhzAIX+RwABAAAAAAAAAA==",
    "_self": "dbs/aDhzAA==/colls/aDhzAIX+RwA=/docs/aDhzAIX+RwABAAAAAAAAAA==/",
    "_etag": "\"00003901-0000-0000-0000-58a4d1620000\"",
    "_attachments": "attachments/",
    "_ts": 1487196514
}

and this is the query.ToString():

{"query":"SELECT TOP 100 * FROM root WHERE (((root[\"testString\"] = \"blah1\") AND (ST_Distance(root[\"GeoLocation\"], {\"type\": \"Point\", \"coordinates\": [-111.9, 33.4]}) <= 10000.0)) AND (root[\"partitionKey\"] IN (\"9tbq\", \"9tbr\", \"9tbw\", \"9tbn\", \"9tbm\", \"9tbx\", \"9tbp\", \"9tbt\", \"9tbj\"))) "}

Looks like it is not respecting JSON.NET property name for the GeoLocation property. The other properties are being respected, though, and the JSON document looks correct.

rnagpal commented 7 years ago

@zfang will follow up on this with you.

zfang commented 7 years ago

Please let us know your SDK version and whether updating to the latest SDK works. You might be using a pretty old SDK.

rnagpal commented 7 years ago

@morganabel Did you tried upgrading to the latest SDK to see if the issue is resolved?

morganabel commented 7 years ago

It is still a problem in the latest version. The problem is the linq to sql is not respecting the jsonproperty name attribute for ST_DISTANCE

rnagpal commented 7 years ago

@mabdelmonemali tried this and it seems to work. Are you using SDK 1.12.0?

morganabel commented 7 years ago

Yes 1.12.0. For whatever reason it does not seem to respect the JSON.net naming rules on that property for me. For now I am just working around by just using the default name for that property. All the other fields work fine with JSON.net property naming.