Prism · Composition

Denormalize a join

Two lists that refer to each other become one: each user comes out with the posts that name them, found with a $filter inside the $map.

The source
{
  users: [
    { id: 'u1', name: 'Ada' },
    { id: 'u2', name: 'Grace' },
    { id: 'u3', name: 'Linus' },
  ],
  posts: [
    { id: 'p1', authorId: 'u1', title: 'On Bernoulli' },
    { id: 'p2', authorId: 'u1', title: 'Engine notes' },
    { id: 'p3', authorId: 'u2', title: 'COBOL origins' },
    { id: 'p4', authorId: 'u3', title: 'Just for fun' },
    { id: 'p5', authorId: 'u3', title: 'Linux history' },
  ],
}
The config
{
  $map: {
    over: { $ref: '$.users' },
    as: 'user',
    body: {
      id: { $get: { from: { $var: 'user' }, path: ['id'] } },
      name: { $get: { from: { $var: 'user' }, path: ['name'] } },
      posts: {
        $filter: {
          over: { $ref: '$.posts' },
          as: 'post',
          when: {
            $eq: [
              { $get: { from: { $var: 'post' }, path: ['authorId'] } },
              { $get: { from: { $var: 'user' }, path: ['id'] } },
            ],
          },
        },
      },
    },
  },
}
What comes out
[
  {
    id: 'u1',
    name: 'Ada',
    posts: [
      { id: 'p1', authorId: 'u1', title: 'On Bernoulli' },
      { id: 'p2', authorId: 'u1', title: 'Engine notes' },
    ],
  },
  {
    id: 'u2',
    name: 'Grace',
    posts: [{ id: 'p3', authorId: 'u2', title: 'COBOL origins' }],
  },
  {
    id: 'u3',
    name: 'Linus',
    posts: [
      { id: 'p4', authorId: 'u3', title: 'Just for fun' },
      { id: 'p5', authorId: 'u3', title: 'Linux history' },
    ],
  },
]
Output matches the expected value

Runs in this page on the installed package. The input and the expected output are defined by the example.