Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure CosmosDB Contains method does not working

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??

like image 350
komluk Avatar asked Dec 11 '25 15:12

komluk


1 Answers

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:

enter image description here

Then changing it to this:

enter image description here

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.

like image 122
Nick Chapsas Avatar answered Dec 13 '25 04:12

Nick Chapsas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!