isawk
isawk

Reputation: 1057

AQL return flat merged list

I want to return a unique list of product options in AQL, I understand COLLECT can return unique list however, how do I now flatten it into an array.

So I want to return the following filtered list: (lets call it list [A])

[
  [
    "Size"
  ],
  [
    "Size",
    "Color"
  ],
  [
    "value"
  ]
]

as: (lets call this list [B])

["Size","Color","Value"]

Query used to obtain list [A]

FOR product IN products
    COLLECT options = product.options[*].option
    FILTER LENGTH( options ) > 0
RETURN options

I tried FLATTEN, UNIQUE and no luck. Perhaps am not using functions accurately. My initial thought would be to repack items in list [A] to create list [B] something like push [A] into [B] if not in [B]

Upvotes: 3

Views: 2031

Answers (1)

stj
stj

Reputation: 9097

FLATTEN should actually work. By default it will collapse items on the first level only, but it can be given an extra argument for the number of levels to collapse.

For example, you can use it with level 3 on a more deeply-nested structure like this:

/* values to flatten */
LET values = [[[["Size"]],[["Size","Color"]],["value"]]]
RETURN FLATTEN(values, 3)

This will return all items and sub-items in a flat array, i.e.

[ 
  "Size", 
  "Size", 
  "Color", 
  "value" 
] 

In the specific example query you posted, using FLATTEN like as follows will not work, because FLATTEN would be invoked individually for each product document:

FOR product IN products
  COLLECT options = product.options[*].option
  FILTER LENGTH( options ) > 0
  RETURN FLATTEN(options, 2)

So it won't produce a single, collapsed array, but multiple, already collapsed arrays of depth 1.

To create a collapsed array from all product documents, the FLATTEN can be applied outside of the FOR loop:

RETURN FLATTEN(
  FOR product IN products
    COLLECT options = product.options[*].option
    FILTER LENGTH( options ) > 0
    RETURN options
)

Upvotes: 4

Related Questions