1

I'm new to JSONATA, so this is probably a pretty easy formatting problem that I don't know yet. I need to take a large object and reduce it down into something more manageable. I've been able to do this with objects, but am running into a problem with a particular data structure. It's metadata from a list of images, where the keywords are in an array of objects each with the structure {"name": "keyword"}. Like this:

{
    "body": {
    "files": [
      {
        "id": 101936854,
        "title": "Taco Salad",
        "keywords": [
          {
            "name": "background"
          },
          {
            "name": "baked"
          },
          {
            "name": "beef"
          }
        ]
      },
      {
        "id": 412961542,
        "title": "Fiji",
        "keywords": [
          {
            "name": "beach"
          },
          {
            "name": "sea"
          },
          {
            "name": "tree"
          }
        ]
      }
    ]
  }
}

When I use the query

$zip(body.files.id,body.files.title,body.files.[keywords.name])
{
    "id": $[0],
    "title": $[1],
    "keywords": $[2]
}

I get what I want, but only the first object, like so:

{
  "id": 101936854,
  "title": "Taco Salad",
  "keywords": [
    "background",
    "baked",
    "beef"
  ]
}

If I add the . to output all the objects, I get back multiple objects but only the first value of name in the array. Like so:

$zip(body.files.id,body.files.title,body.files.[keywords.name]).
{
    "id": $[0],
    "title": $[1],
    "keywords": $[2]
}

Gets:

[
  {
    "id": 101936854,
    "title": "Taco Salad",
    "keywords": "background"
  },
  {
    "id": 412961542,
    "title": "Fiji",
    "keywords": "beach"
  }
]

I believe this is because the input objects in that array all have the same key of name. So, I need to somehow get all the values of name and put them in one array called keywords.

1 Answer 1

2

If I'm not mistaken, you want something like this:

body.files.{
  "id": id,
  "title": title,
  "keywords": keywords.name
}

or, you can play with the transform operator:

(body ~> |files|{ "keywords": keywords.name }|).files

which produces this output for your example:

[
  {
    "id": 101936854,
    "title": "Taco Salad",
    "keywords": [
      "background",
      "baked",
      "beef"
    ]
  },
  {
    "id": 412961542,
    "title": "Fiji",
    "keywords": [
      "beach",
      "sea",
      "tree"
    ]
  }
]

See it live here https://stedi.link/ybzLADi and here https://stedi.link/TLk7Loq

P.S. if you do want to use $zip for it, I think you'd have to avoid arrays of arrays to prevent JSONata from flattening results, one possible implementation:

$zip(
  body.files.id, 
  body.files.title, 
  body.files.{"keywords": keywords.name}
).{
  "id": $[0], "title": $[1], "keywords": $[2].keywords
}
Sign up to request clarification or add additional context in comments.

1 Comment

Excellent, thanks! Indeed, that was a way more streamlined approach to avoid the $zip function. The zip function you provided also worked well, and thanks for providing that. The way that the function treats the inputs makes way more sense with that example, so I learned a good bit from that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.