Skip to main content

Object Merge

Mutate

Synopsis

Merges two or more object fields into a single object. Where the same key appears in more than one, the leftmost field wins.

Schema

- object_merge:
fields: <string[]>
description: <text>
if: <script>
ignore_failure: <boolean>
ignore_missing: <boolean>
on_failure: <processor[]>
on_success: <processor[]>
tag: <string>
target_field: <ident>

Configuration

The following fields are used to define the processor:

FieldRequiredDefaultDescription
fieldsY-Object fields to merge, in precedence order. At least two are required
descriptionN-Explanatory note
ifN-Condition to run
ignore_failureNfalseSee Handling Failures
ignore_missingNfalseIf true, quietly exit if field doesn't exist
on_failureN-See Handling Failures
on_successN-See Handling Success
tagN-Identifier
disabledNfalseWhen true, the processor is skipped and the event continues to the next one. Lets you take a processor out of the path without removing its configuration
target_fieldNfirst entry of fieldsField to store the merged object. Defaults to the first field listed, replacing it

Details

Order is precedence: the first field listed wins a key conflict. Each field is read left to right and a key is taken only if it is not already present, so later fields fill gaps rather than overwriting. Put the authoritative source first.

The merge is shallow. A key whose value is itself an object is taken or skipped whole; the nested objects are not merged into each other.

Three cases are handled rather than failing:

CaseBehavior
Fewer than two fields configuredError — the processor requires at least two
One of the fields is missing or nullSkipped, and the remaining fields still merge
Every field is missingError, reporting the first field that could not be read
A field holds something other than an objectError

That middle row is the useful one: a merge across optional enrichment sources succeeds as long as at least one of them arrived.

Examples

Merging Enrichment Sources

Combining two enrichment results into one object...

{
"geo": {"country": "DE", "city": "Berlin"},
"asn": {"org": "Example ISP", "number": 64512}
}
- object_merge:
fields: ["geo", "asn"]
target_field: source.enrichment

leaving both sources in place:

{
"geo": {"country": "DE", "city": "Berlin"},
"asn": {"org": "Example ISP", "number": 64512},
"source": {
"enrichment": {
"country": "DE",
"city": "Berlin",
"org": "Example ISP",
"number": 64512
}
}
}

Precedence on Conflict

Where both objects carry the same key, the first listed wins...

{
"observed": {"country": "DE", "source": "sensor"},
"defaults": {"country": "US", "tier": "standard"}
}
- object_merge:
fields: ["observed", "defaults"]
target_field: resolved

so defaults fill gaps but never override:

{
"observed": {"country": "DE", "source": "sensor"},
"defaults": {"country": "US", "tier": "standard"},
"resolved": {
"country": "DE",
"source": "sensor",
"tier": "standard"
}
}

A Missing Source

An absent field is skipped rather than failing the merge...

{
"geo": {"country": "DE"}
}
- object_merge:
fields: ["geo", "asn"]
target_field: source.enrichment

so the enrichment that did arrive is still written:

{
"geo": {"country": "DE"},
"source": {
"enrichment": {"country": "DE"}
}
}