{
  "schema_version": 2,
  "id": "integrate/redis-data-integration/data-pipelines/transform-examples/redis-write-same-key",
  "title": "Write to the same key from multiple jobs",
  "url": "https://redis.io/docs/latest/integrate/redis-data-integration/1.19.1/data-pipelines/transform-examples/redis-write-same-key/",
  "summary": "",
  "content": "\nUse this pattern when two or more jobs write related source entities, such as\n`customer` and `address`, to the same Redis JSON document.\n\nWhen multiple jobs write to the same Redis key, a delete event from any of the\nsource entities can delete the key from the target. To work around this, use\n[`row_format: full`](https://redis.io/docs/latest/integrate/redis-data-integration/1.19.1/data-pipelines/transform-examples/redis-row-format#full)\nso the job can inspect the\n[`opcode`](https://redis.io/docs/latest/integrate/redis-data-integration/1.19.1/data-pipelines/transform-examples/redis-opcode-example),\nconvert delete events into update events before writing to Redis, and write JSON\ndocuments with `on_update: merge`.\n\n\u003e [!NOTE]\n\u003e Use the same key expression in all jobs that write to the shared Redis key. For\n\u003e delete events, read key values from `before` or `key` because `after` is `null`.\n\n## Customer job\n\n```yaml\n# jobs/customer.yaml\nname: customers\n\nsource:\n  table: customers\n\noutput:\n  - uses: redis.write\n    with:\n      data_type: json\n      on_update: merge\n      key:\n        expression: concat(['customer:', id])\n        language: jmespath\n\n```\n\n## Address job\n\nFor delete events from the `addresses` table, this job sets all fields to `null`\nto instruct RDI to remove them from the target JSON document. This behavior is\navailable in RDI 1.15.0 or later when native JSON merge is enabled and the target\ndatabase uses RedisJSON 2.6.0 or later.\n\n```yaml\n# jobs/addresses.yaml\nname: addresses\n\nsource:\n  table: addresses\n  row_format: full\n\ntransform:\n  - uses: add_field\n    with:\n      fields:\n        # For create/update records, we take the new values as is.\n        # If the record is a deletion, we set all fields to null.\n        - field: after\n          expression: |\n            (opcode != 'd' \u0026\u0026 after) \n              || \n            from_entries(to_entries(before)[].{key: key, value: `null`})\n          language: jmespath\n\n        # Treat deletes as updates so that we can use the same output configuration\n        - field: opcode\n          expression: opcode == 'd' \u0026\u0026 'u' || opcode\n          language: jmespath\n\n  # If you have overlapping field names (for example, FK and PK have the same name, or both tables have\n  # a field called \"id\"), you may want to remove the field from the after object to prevent it\n  # from overwriting the PK.\n  - uses: remove_field\n    with:\n      field: after.id\n\noutput:\n  - uses: redis.write\n    with:\n      data_type: json\n      on_update: merge\n      key:\n        expression: concat(['customer:', after.customer_id || before.customer_id])\n        language: jmespath\n```\n",
  "tags": ["docs","integrate","rs","rdi"],
  "last_updated": "2026-09-19T17:55:58-07:00"
}
