-
Notifications
You must be signed in to change notification settings - Fork 501
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Query: Adds ArrayContains to CosmosLinqExtensions to allow partial matching on array fields in queries #4992
base: master
Are you sure you want to change the base?
Query: Adds ArrayContains to CosmosLinqExtensions to allow partial matching on array fields in queries #4992
Conversation
3c89ee6
to
e7785f8
Compare
@microsoft-github-policy-service agree company="Solarvista Software LTD" |
8ec125f
to
f6b6d84
Compare
The `Array_Contains` funtion CosmosDB Sql has a 3rd parameter which allows it to do a partial match on the given item. This is unable to be called with the built in Linq `array.Contains(item)` extension methods. This adds this adds an explicit mapping to this function to allow it to be called in Linq like this: `documents.Where(document => document.ObjectArray.ArrayContains(new { Name = "abc" }, true))`
f6b6d84
to
786db81
Compare
@bcrobinson technically adding this functionality makes sense. However, ARRAY_CONTAINS with partial match is a very expensive function (both RU consumption and latency wise) and use of it is generally discouraged in favor of another pattern. |
new LinqTestInput("ArrayContains in Select clause with int value and match partial false", b => getQuery(b).Select(doc => doc.ArrayField.ArrayContains(1, false))), | ||
new LinqTestInput("ArrayContains in Filter clause with int value and match partial false", b => getQuery(b).Where(doc => doc.ArrayField.ArrayContains(1, false))), | ||
new LinqTestInput("ArrayContains in Select clause with object value and match partial false", b => getQuery(b).Select(doc => doc.ObjectArrayField.ArrayContains(new { Field = "abc" }, false))), | ||
new LinqTestInput("ArrayContains in Filter clause with object value and match partial false", b => getQuery(b).Where(doc => doc.ObjectArrayField.ArrayContains(new { Field = "abc" }, false))), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also include coverage for ArrayContains without third parameter?
Pull Request Template
Description
The
Array_Contains
function CosmosDB Sql has a 3rd parameter which allows it to do a partial match on the given item. This is unable to be called with the built in Linqarray.Contains(item)
extension methods.This adds this adds an explicit mapping to this function to allow it to be called in Linq like this:
Remarks
New extension method called
ArrayContains
instead ofContains
I namef the new
CosmosLinqExtensions
extension methodArrayContains
instead ofContains
as the other extensions methods matched thier Cosmos Sql counterparts and because this is for a direct invokation of this function.Can change the name if you require.
ArrayContains
SignatureThe
itemToMatch
paramater is anobject
as it will need to take anonymous objects (and c# doesn't have a similar concept to typescript'sPartial<T>
). If was generic callers would be force to pass in an object of the same type, and the default serialiser creates object with every property that exists on the class. So the created query object with default values (e.g. Array_Contains(root["Items"],{ "I" = 0, "s" = null })
)which would the cause Cosmos to try and match on all properties.Because it's not generic the
obj
is thenIEnumerable
, so it would at a minimum only work on iterable values.If this was
ArrayContains<T>(this IEnumerable<T> obj, T itemToMatch, bool partialMatch)
then we'd need to always pass the sameT
type to this method, and the serialiser would then serialise all the properties on the typeT
, which would cause the partial matching in cosmos to fail. The downside is you loose some type checking (the anonymous object could have a property name typed wrong),Modification to
ArrayContainsVisitor
The
ArrayContainsVisitor
visitor already exists for theContains
Linq mappings, the I modified this to work with the different extension version for Array Contains.Type of change
Closing issues
closes #4991
To automatically close an issue: closes #IssueNumber