0

I have in my bucket a document containing a list of ID (childList). I would like to query over this list and keep the result ordered like in my JSON. My query is like (using java SDK) :

String query = new StringBuilder().append("SELECT B.name, META(B).id as id ") .append("FROM" + bucket.name() + "A ") .append("USE KEYS $id ") .append("JOIN" + bucket.name() + "B ON KEYS ARRAY i FOR i IN A.childList end;").toString();

This query will return rows that I will transform into my domain object and create a list like this :

n1qlQueryResult.allRows().forEach(n1qlQueryRow -> (add to return list ) ...);

The problem is the output order is important.

Any ideas?

Thank you.

Community
  • 1
  • 1
Magmix
  • 13
  • 4
  • You should be able to simply append an `ORDER BY` clause to the end of your query: https://developer.couchbase.com/documentation/server/current/n1ql/n1ql-language-reference/orderby.html – Jerod Johnson Jan 05 '17 at 15:03
  • The list is a list of String. Let's call it chlidList. I need childList[0] to be the first row and so on. If I will use ORDER BY clause it will be ordered using the String order. – Magmix Jan 05 '17 at 16:42
  • do you always start from 1 single document for the join? If so, why not perform k/v operations instead of a N1QL query? you will get more control vs the JOIN on the order in which you fetch the B documents... – Simon Baslé Jan 05 '17 at 19:08

1 Answers1

0

here is a rough idea of a solution without N1QL, provided you always start from a single A document:

List<JsonDocument> listOfBs = bucket
      .async()
      .get(idOfA)
      .flatMap(doc -> Observable.from(doc.content().getArray("childList"))) 
      .concatMapEager(id -> bucket.async().get(id))
      .toList()
      .toBlocking().first();

You might want another map before the toList to extract the name and id, or to perform your domain object transformation even maybe...

The steps are:

  1. use the async API
  2. get the A document
  3. extract the list of children and stream these ids
  4. asynchronously fetch each child document and stream them but keeping them in original order
  5. collect all into a List<JsonDocument>
  6. block until the list is ready and return that List.
Simon Baslé
  • 27,105
  • 5
  • 69
  • 70