Filter documents using n1ql

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-23 02:38:12

问题


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

  1. Make an array with albums in the SELECT statement by using array_agg() function;
  2. Use ARRAY_SORT() to sort this array by specific field (album.creationDate). This function sorts only in ASC order.
  3. Use ARRAY_REVERSE() to reverse the order to get the latest album


来源:https://stackoverflow.com/questions/43973978/filter-documents-using-n1ql

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!