问题
I have two types of documents with a relation one to many and I need to get only one document basing on the latest date value. Here it is an example:
Document Type (Singer):
{
"id":"223-34fd-35325-dsf-343f",
"resourceType":"Singer",
"name":"Paul"
}
Document Type (Album1):
{
"id":"456-d435-43g346-43-436tf-345g",
"name":"Amazing night",
"author":"223-34fd-35325-dsf-343f",
"creationDate": "2017-05-12T07:57:51.458Z"
}
Document Type (Album2):
{
"id":"878-ffe6-43gs56-5hn7-ffgdd-345hd",
"name":"Be quiet",
"author":"223-34fd-35325-dsf-343f",
"creationDate": "2017-05-11T13:43:05.580Z"
}
Well, I need to get a list of Singers with only one album (which was the last added, basing on creationDate
). In my case I have to get singer "Paul" and the album "Amazing night". Is this either possible?
回答1:
If You need Album document use the following query.
SELECT singer, MAX([a.creationDate, a])[1] latestAlbum
FROM default a
WHERE a.author IS NOT MISSING
GROUP by a.author
LETTING singer = (SELECT RAW s.name FROM default s USE KEYS a.author)[0];
回答2:
Ofcourse it is possible.. Try this query:
SELECT singer,
FIRST x.name FOR x IN ARRAY_AGG({a.creationDate, a.name})
WHEN x.creationDate = max(a.creationDate) END
AS latestAlbum
FROM default a
WHERE a.author IS NOT MISSING
GROUP by a.author
LETTING singer = (SELECT RAW s.name FROM default s USE KEYS a.author)[0];
Most of the magic is in the 'FIRST' N1QL expression in the projection that computes the latestAlbum. Here,
- the ARRAY_AGG({...}) expression dynamically creates an array of objects with createDate & album name for each singer (from the GROUP BY)
- the FIRST expression returns the first such element in the above array which matches the WHEN condition, with MAX creationDate value. Note that, your date format used is in lexical sort order so we din't need any date format processing for sorting date values.
- the singer name is obtained with the subquery in LETTING class
Btw, you can use ARRAY construct (instead of the FIRST) if you want to get all latest albums with same creationDate
ARRAY x.name FOR x IN ARRAY_AGG({a.creationDate, a.name})
WHEN x.creationDate = max(a.creationDate) END
AS latestAlbum
Cheers!!
回答3:
I also figured out an option to get the latest album:
SELECT singer.name as singertName, ARRAY_REVERSE(ARRAY_SORT(array_agg(album.creationDate)))[0] as album from bucket
where type='album' and album.author = "223-34fd-35325-dsf-343f" group by album.author order by album.author
- Make an array with albums in the
SELECT
statement by usingarray_agg()
function; - Use
ARRAY_SORT()
to sort this array by specific field (album.creationDate
). This function sorts only inASC
order. - Use
ARRAY_REVERSE()
to reverse the order to get the latest album
来源:https://stackoverflow.com/questions/43973978/filter-documents-using-n1ql