I'm not sure but I think that I found a bug in Azure Cosmos DB. Here is my situation. I have the following JSON
{
"id": "token",
"User": {
"UserToken": "token",
"Email": "[email protected]"
},
"_ts": 1521728825
}
And I wrote a following query using LINQ:
await _dbClient.Where<UserDocument>(_collectionUri,feedOptions,
d => d.User.UserToken == searchString
|| d.User.Email.Contains(searchString))
.OrderByDescending(d => d.Timestamp)
.AsDocumentQuery().ToListAsync())
When I run it with searchString=="token" it will return an empty list, so I decide to modify the query:
await _dbClient.Where<UserDocument>(_collectionUri,feedOptions,
d => d.User.UserToken == searchString)
.OrderByDescending(d => d.Timestamp)
.AsDocumentQuery().ToListAsync())
Magically it started working. Can someone tell me what am I doing wrong? or maby there is an issue with CONTAINS method in CosmosDB??
This isn't a bug. It has to do with your collection's Indexing policy.
I don't know what your indexing policy currently looks like but when an exact match works and a partial match doesn't, on a string, then it's safe to say that you are using a Hash index for your Strings.
When using hash, only equality checks will return values. You will need to change your string index to Range and precision -1 to partially match strings.
You can find your index settings under the Scale & Settings section of the Data explorer.
If your indexing policy looks like this:

Then changing it to this:

Should work.
You can however limit this even more and only index the /User/Email/? as a Range and keep the rest as Hashes.
You can also override this behaviour by providing a FeedOptions object with the value EnableScanInQuery set to true. However I've got mixed results with this so I'd go with the index change.
I highly recommend you talk a look at the indexing documentation here. There is also a great video explaining more about it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With