OData - filter by nested property - odata

does anyone know how to express an OData $filter against a nested property?
for ex. I have the following Atom entry,
<entry>
...
<m:properties>
...
<d:RegardingObjectId m:type="Microsoft.Crm.Sdk.Data.Services.EntityReference">
<d:Id m:type="Edm.Guid">3f3712fd-fc49-e211-8eb8-000c296272c8</d:Id>
<d:LogicalName>new_sportsleague</d:LogicalName>
<d:Name>Boca</d:Name>
</d:RegardingObjectId>
I want to filter for those entries that have RegardingObjectId/LogicalName eq 'new_sportsleague'.
Tried with 'RegardingObjectId/LogicalName' and 'RegardingObjectId.LogicalName' with no luck.

'RegardingObjectId/LogicalName' would be the correct syntax.
For example:
http://services.odata.org/v3/OData/OData.svc/Suppliers
returns two results, whereas
http://services.odata.org/v3/OData/OData.svc/Suppliers?$filter=Address/Street eq 'NE 228th'
returns just one.
I don't see a place in the OData spec that explicitly states whether filtering using properties of a complex value is legal or not, but it seems that WCF Data Services supports it. It could be that other OData implementations don't.

Use following odata API example to access nested properties with filter data
http://192.168.50.152:50086/odata/StationOperationLogs/?$expand=ProductionStation,ProductionStation/ProductionUnit&$filter=ProductionStation/ProductionUnit/Id eq 2

Related

multiple exclude data can't catch in filter option odata

I create smart table sapui5 screen by using odata (S4Hana) .
On the odata side, get the filter value from smart filter by using this method ⇒ [ io_tech_request_context->get_filter( )->get_filter_select_options( ).]
It is ok when I pass the filter value as multiple Include option .
When I pass the filter value as multiple Exclude option , the data can't access from filter_select option method. The data can be get in filter_string method but it is difficult to get the data and put to range table .
Let me know how to get the filter value from entity set of odata .
Let me know how to get the filter value from entity set of odata .
There are defined rules, how your $filter parameter has to look like to get converted into the import parameter it_filter_select_options. If you breach this rules (you did...) the import parameter it_filter_select_options will be empty.
Sadly, there's no simple solution.
If you need to convert the parameter iv_filter_string into select options there are quite a few Tutorials/Blogs about it.
Filter String How To
How to Parse IV_FILTER_STRING in GET_ENTITYSET

How to correctly query OData with filter in nested type based on property from parent type?

I am getting a dynamic value (_FilterDate) on the parent type that I want to use as a filter for the nested type /Trips but can't get it to work because I still get entries in the nested data that do not meet the filter. Actually, there is no difference whether I use this filter or not.
$filter=Trips/all(d:d/EndDate ge _FilterDate)
I also tried this:
$expand=Trips($filter=EndDate ge $it/_FilterDate)
but got the error: "Could not find a property named '_FilterDate' on type 'Default.Trips'."
So I'm wondering how to get the syntax right and thus kindly ask for help.
Example portion:
"value": [
{
"_FilterCompany": "YES",
"_FilterLocation": "YES",
"_FilterDate": "2020-01-08",
"Trips": [
{
"StartDate": "2019-06-24",
"EndDate": "2019-06-28",
},
{
"StartDate": "2020-02-07",
"EndDate": "2020-02-07",
}
]
}
There are two issues going on here:
this response is specifically regarding the OData v4 specification and the .Net ODataLib implementation.
You have correctly identified that when filtering results based on a nested collection you you must separately apply the filter within that collection if you want the fitler to apply to the items within that collection as well.
This is because the root level $filter criteria only affects the selection of the root items, think of it as if the $expand operator is applied after the $filter has identified the top level of row the return, $expand is simply executed as a Linq Include statement.
In your second attempt, $it references the instance of Trips, which is a known bug/by design, according to the spec it is expected to work the way you have implemented it:
5.1.1.6.4 $it
Example 82: customers along with their orders that shipped to the same city as the customer's address. The nested filter expression is evaluated in the context of Orders; $it allows referring to values in the outer context of Customers.
http://host/service/Customers?
$expand=Orders($filter=$it/Address/City eq ShipTo/City)
So knowing the $it is broken, the spec doc does specify a $root identifier that you might also be able to use, but in ODataLib 7.3 $root is still not supported OOTB either. There is an issue logged here: $it references the wrong resource #616
Workaround
If your Trips data type has a navigation property back to the Filter/root record, then you can use that navigation property as part of the $filter:
Assuming the navigation property is called Filter
$filter=Trips/all(d:d/EndDate ge _FilterDate)&$expand=Trips($filter=EndDate ge Filter/_FilterDate)
If your Trips type does not have this navigation link back to the parent record then you are stuck at this stage with these two workarounds:
Create a Function on the controller to return this filtered data specifically, as this would be simple to evaluate as a Linq query in the server-side.
Accept that the server will return extra rows in the Trips collections, and apply the filter over the results in the client-side.

Getting some data from Microsoft Graph unified OData endpoint

How to count number of items in EntitySet of MicrosoftGraph, for example 'users' or 'groups'? I tried:
https://graph.microsoft.com/v1.0/users?$count
Returns: lists all users
https://graph.microsoft.com/v1.0/users/$count
Returns:
{ "error": { "code": "Request_BadRequest", "message": "Unexpected segment Edm.Int32.", } }
Also in Annotations of target "microsoft.graph.directoryObject" which are those EntitySets based on I see that it is Selectable=false, Countable=false ...
Will $skip be ever available on 'users' or other toplevel EntitySet items ( https://graph.microsoft.com/v1.0/groups?$skip=5 ) ? It is available on other items ( https://graph.microsoft.com/v1.0/me/contacts?$skip=5 ). I know about $skipToken, but it is not the same.
Can I find somewhere in the $metadata if property is sortable? For example user.displayName is sortable, but user.mail or user.givenName are not. This would be handy in the $metadata. Is there plan to introduce this into $metadata?
OrderBy DESC in this formula https://graph.microsoft.com/v1.0/users?$orderBy=displayName%20desc is ignored, it shows items ordered ASC, am I doing something wrong?
Not much help I know, but if you do an API call that gets a Collection you can get a count using the second form you gave in the first question. Eg:
https://graph.microsoft.com/v1.0/users/<id>/events/$count
returns the count (6 in my case, and not in JSON - the returned data is actually "\x{ef}\x{bb}\x{bf}6" (in Perl formatting)). If we use the ? as the last separator (which is what http://graph.microsoft.io/en-us/docs/overview/query_parameters seems to indicate we should) with this URL:
https://graph.microsoft.com/v1.0/users/<id>/events?$count
I just get the list of events with no count as you do.
So that seems to indicate two things to me:
a) The $count doesn't appear to work as a query parameter, despite the documentation and the OData standards saying it should,
and
b) There seems to be a bug in the API for handling EntitySets which isn't there for Collections.
Sorry I can't be of more help, but its another data point at least (I just came unstuck with the same thing which is why I noticed this StackOverflow post!)
Ad 1. https://graph.microsoft.com/v1.0/users/$count is the correct OData syntax (http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/part2-url-conventions/odata-v4.0-errata02-os-part2-url-conventions-complete.html#_Toc406398087), but as indicated in the metadata directoryObject collections are not currently countable. ODataV4 also allows $count in query parameters (http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/part2-url-conventions/odata-v4.0-errata02-os-part2-url-conventions-complete.html#_Toc406398166), but then it should be specified with true or false value (e.g. https://graph.microsoft.com/v1.0/me/events?$count=true) and the response will include both the collection and its count in the #odata.count property. This is again not supported for directoryObject collections.
Ad 2. There is no plan right now to support $skip for directoryObject collections.
Ad 3. Yes, we plan to indicate which properties are sortable by in metadata using the SortRestrictions annotation defined in the OData capabilities vocabulary (http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/vocabularies/Org.OData.Capabilities.V1.xml)
Ad 4. Your request is correct, but we only support sorting users by displayName in the ascending order.

oData inner filter in $expand

Currently I am facing some issues while querying the oData services. I am very new to oData query syntax.
I am trying to query oData service using the following url
https://mysite/DataQueryGroups?$select=Id,Name&$filter=IsHidden eq false&IsShared ne false&$expand=DataQueries($select=Id,Name,IsPinned;)
which returns the desired results to me. Above query basically returns all DataQueryGroups where IsHidden=false and IsShared<>false, including the its child entity DataQueries.
Now I want to add filter to the DataQueries enity to display only those resulsts where IsPinned = true. So I have tried the following query
https://mysite/DataQueryGroups?$select=Id,Name&$filter=IsHidden eq false&IsShared ne false&$expand=DataQueries($select=Id,Name,IsPinned;$filter=IsPinned eq true;)
But this returns me the same results and it looks like its not considering the inner filter/last filter which I have specified on DataQueries entity.
I would like to know how to filter on parent and child entities and return the fields from both.
I am finding difficulties to under this syntax. Please let me know if anybody can help me on this issue.
I am using oData version 4.0
Thanking you in advance
Deepak
#Deepak
It seems that the latest Web API OData (v5.7) supports the nested filter in expand. See this issue: https://github.com/OData/WebApi/issues/127
I also wrote a sample project based on your model. It works on my side.
Would you please run it at your side and let me know any result. Thanks.

OData call with $filter and $expand simultaneously

I've been trying to call a entity, but i'm supposed to call the results from its associated entities. I tried to do it with the following URL:
/sap/opu/odata/XXXXXXXX/SERVICE_NAME/MatnrGetdetailCollection?$filter=IVendorId eq '1701' and ILanguage eq 'P' and IMaterial eq 'M-05'&$expand=MatnrClassGetdetail
I must use the filter because the called function has these mandatory parameters.
Am I making any mistake on the URL or the error isn't there?
In general $filter and $expand can be combined, we use it in our application. Therefore please see Layla's Comment. In addition, you should tell us what the actual error is.
If MatnrGetdetailCollection is indeed an entity set, then the corresponding entity must have a navigation property of the name MatnrClassGetdetail, otherwise $expand won't work.
There is some problem with the URL when you want to go for obligatory parameters. Please pass them as key values in segw and and go for the format I'm sending:
/sap/opu/odata/sap/SERVICE_NAME/EntitySet(keyfield='value',keyfield='value')/?$expand=navigationName

Resources