on 08-20-2019 3:17 PM
Hi,
Is there a way to count the number of associated entities using CDS? Let's say I'd like to display the number of books written by a particular author:
entity Books {
key ID : Integer;
title : localized String;
author : Association to Authors;
}
entity Authors {
key ID : Integer;
name : String;
books : Association to many Books on books.author = $self;
@Core.Computed
numberOfBooks : Integer;
}
I tried something like count(books) as numberOfBooks but it's not supported 🙂
Cheers,
Pierre
I wrote up one possible answer in the form of a blog post:
https://blogs.sap.com/2019/08/21/computed-field-example-in-cap/
Hope that helps!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you for this very detailed answer DJ!
Pierre
Hi Pierre,
it is possible to define the view on CDS level to push down the count calculation to the database. You just need to do a minimal adaption of the view definition in DJ's example:
service CatalogService {
entity Books as projection on my.Books;
entity Authors as select from my.Authors {
*,
@Core.Computed
count(1) as numberOfBooks: Integer
};
}
Hope this helps,
Johannes
Hi Johannes,
This doesn't really work as intended because then numberOfBooks contains the total number of authors and the response only contains 1 author:
{
"@odata.context": "$metadata#Authors",
"@odata.metadataEtag": "W/\"8q5jjLD6vJ0ARrjnkajTONXIn38vpa1wxoXucua4kzU=\"",
"value": [{
"ID": 101,
"name": "Emily Brontë",
"numberOfBooks": 4
}]
}<br>
This is what I get with DJ's solution:
{
"@odata.context": "$metadata#Authors",
"@odata.metadataEtag": "W/\"8q5jjLD6vJ0ARrjnkajTONXIn38vpa1wxoXucua4kzU=\"",
"value": [{
"ID": 101,
"name": "Emily Brontë",
"numberOfBooks": 1
},
{
"ID": 107,
"name": "Charlote Brontë",
"numberOfBooks": 1
},
{
"ID": 150,
"name": "Edgar Allen Poe",
"numberOfBooks": 2
},
{
"ID": 170,
"name": "Richard Carpenter",
"numberOfBooks": 1
}
]
}<br>
EDIT: here's a solution, using count at the CDS level:
service CatalogService {
entity Books as projection on my.Books;
entity Authors as select from my.Authors, my.Books {
key Authors.ID,
name,
@Core.Computed
count(Books.ID) as numberOfBooks: Integer
} where Authors.books.ID = Books.ID
group by Authors.ID;
}
cds compile .\srv\cat-service.cds --to sql:
CREATE VIEW CatalogService_Authors AS SELECT
Authors_0.ID,
Authors_0.name,
COUNT(Books_1.ID) AS numberOfBooks
FROM ((my_bookshop_Authors AS Authors_0 CROSS JOIN my_bookshop_Books AS Books_1) LEFT JOIN my_bookshop_Books AS Books_2 ON (Books_2.author_ID = Authors_0.ID))
WHERE Books_2.ID = Books_1.ID
GROUP BY Authors_0.ID;
Cheers,
Pierre
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I would think you should watch this episode of Hands-on SAP dev with dj.adams.sap where he showed how to create a calculated value.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks Gregor, I'll watch this episode. Now I'm curious and wondering if DJ's solution involves hooks/handlers.
dj.adams.sap : no but I'll watch the replay at home or wait for the annotated version on YT.
In the OData standard this case is described here: https://www.odata.org/documentation/odata-version-2-0/uri-conventions/
Example:
https://services.odata.org/OData/OData.svc/Categories(1)/Products/$count
This would be ../Authors(3)/books/$count then. Would be interesting to know if this works out of the box or if you have to do some coding in CDS or if it is not implemented yet in CDS.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
77 | |
9 | |
7 | |
6 | |
6 | |
6 | |
6 | |
6 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.