Neo4j acquires GraphAware. Learn more about this exciting new chapter.

Entity resolution 102: Who decides two records are the same person?

September 2, 2026 · 11 min read

In the first post in this series, we introduced Robert Miller, or was it Rob Miller, born 1982-04-03, a few miles away in Salford? Same person, two records, and nothing in either system told anyone that. We made the case that entity resolution matters, and we were upfront about something important: GraphAware Hume isn’t an entity resolution engine. It doesn’t decide whether Robert and Rob are the same person.

So who does? And once that decision is made, what happens next? This post answers both questions.

We’ll look at what a dedicated entity resolution engine, using Senzing as our example, actually does under the hood. Then we’ll get into the mechanics of how that decision becomes something an analyst can work with inside GraphAware Hume: how a match becomes a resolved entity, how the original records survive untouched, and what an analyst sees when they encounter one.

Why a dedicated engine, and not just rules

An entity resolution engine like Senzing answers two different questions at once. The first is “who is who?”, working out when different records describe the same real-world entity. The second is “who is related to whom?”, surfacing likely relationships between entities that weren’t previously connected in the data.

That second question matters just as much as the first. A resolved match is useful on its own, but a suggested relationship is something a graph can act on directly: a new edge to add, a new path for graph algorithms to explore, a new lead for an analyst to follow. Entity resolution isn’t just deduplication. It’s also a source of new connections the graph didn’t have before.

It’s tempting to think entity resolution is something you could handle with a few SQL joins and some fuzzy string matching. For a narrow, well-behaved dataset, that might even work for a while. It stops working the moment you’re dealing with real volumes of real-world data: multiple sources, inconsistent formatting, missing fields, names and scripts that vary across languages and cultural naming conventions, and, as we covered in post one, genuine ambiguity that no formatting rule can resolve.

This is the job Senzing is built for. It’s a purpose-built entity resolution engine that uses principle-based matching rather than relying solely on rules. Instead of asking whether a single attribute matches, it considers the available evidence across a pair of records and assesses how strongly that evidence indicates they represent the same person. Some attributes carry more weight than others: a matching passport number, for example, is much stronger evidence than a matching first name, and Senzing’s scoring reflects that.

This kind of matching works best in a specific condition: when many attributes are available that aren’t strongly correlated with each other. The more independent signals there are, the more confidently a principle-based engine can separate genuine matches from coincidental overlap. A dataset with only a name and an approximate year of birth doesn’t give an engine like this much to work with, no matter how well it’s tuned. 

Two things make a dedicated engine worth choosing over building this yourself

Scale and real-time operation
Senzing is built to resolve records as they arrive, rather than only in scheduled batches. A new record from a border crossing system can be scored against what is already known, in real time, with a resolution decision following immediately.

Explainability by default
Every Senzing match comes with a “why” attached. The how/why APIs behind it return the specific attribute combinations and confidence scores that drove a decision, not just a match, but a defensible account of the match. That matters enormously in law enforcement, financial crime, and intelligence work, where “trust me” isn’t an acceptable answer to “why are these the same person?”

One more point, which connects directly to my previous blog post: good data engineering still comes first. Where a stable identifier already exists, such as a passport number, company registration code, or officer ID, that deterministic link should be used directly. An entity resolution engine should handle the residual ambiguity that can’t be resolved that way, not stand in for basic data hygiene.

From a Senzing decision to a resolved entity in the graph

Senzing decides Robert Miller from the police database and Rob Miller from the border crossing system are the same person. What happens to that decision?

The source records are never overwritten or deleted

This is the same “no golden record” principle from post one. Whichever modelling approach is used, GraphAware Hume never overwrites or deletes the original source records. Instead, it creates a distinct node representing the resolved entity, and links each source record to it via a RESOLVED_TO relationship. The police record stays exactly as it was booked. The border crossing record stays exactly as it was captured. Neither one is altered.

What differs between the two modelling approaches is what happens above the source records, not to them.

There are two ways to model this resolved entity:

Fused Entity: The resolved entity is created as a node of the same type as its constituent parts, in this case a Person node, and every relationship the source records had gets copied onto it. An analyst navigating the graph encounters it as a single, unified person, with clean traversal and no extra hops. This is the highest-performing, most analyst-friendly option, and it’s the default choice unless there’s no reason not to use it.

Entity Group: The resolved entity is a distinct EntityGroup node that acts as an identity anchor, without copying relationships onto it. Source records retain their own access controls. This model is useful when records from different sources have different clearance levels or cannot legally be aggregated for every analyst who might access them. The choice is therefore driven by security, access control, and data segregation requirements.

Either way, the underlying principle is the same: resolution sits on top of the raw data rather than replacing it. If a match later turns out to be wrong, the resolution can be removed without reconstructing the original records. 

This is a helpful safety net for reversing bad decisions, and it also helps analysts make informed decisions. 

Different sources sometimes contradict each other: one record gives an address in Manchester, another gives Salford, while a third gives a different date of birth. If those results were merged into one “clean” record, the analyst would never see the contradiction. They’d just see whichever version happened to win. 

A verified government record and an open-source intelligence feed, for example, should not automatically carry the same evidential weight simply because both contribute to the same resolved entity. Keeping source records intact preserves both the contradiction and its provenance, so the analyst can weigh the evidence based on its source. 

The other reason: data retention

Regulations or internal policy may require removing a specific source’s data from the system after a defined period, or on request, without disturbing anything else built on top of it. 

This is exactly the scenario the Entity Group model is suited for. Because constituent records are linked to the Entity Group rather than fused into it, you can delete a single source record cleanly. The Entity Group persists, still correctly connected to every other constituent record, with no trace of having depended on the one that’s now gone.

A Fused Entity, by contrast, has relationships copied onto the resolved entity. Removing a source afterwards therefore requires tracing those relationships back to their source and handling them accordingly. Where retention requirements are known in advance, this can be a reason to choose Entity Groups independently of security or access-control considerations.

Resolution isn’t a one-time write

Records keep arriving, so your entity resolution engine should keep re-evaluating. Sometimes that means a new record links to an existing resolved entity. Sometimes it means new evidence splits an entity that was previously merged, two people the engine now believes are different after all. Occasionally, two separate resolved entities merge into one, once enough new evidence accumulates.

GraphAware Hume’s integration with Senzing has to track all three outcomes and update the graph accordingly, including detecting when a Senzing entity ID that existed yesterday has effectively disappeared today because it was absorbed into another. This can run in near real time, using Neo4j’s change data capture to trigger re-resolution as new data lands in the graph, or in scheduled batches, depending on how current the picture needs to be.

Hume Orchestra and entity resolution engine Senzing pipeline

What this actually looks like to an analyst

None of the above is worth much if it doesn’t make the analyst’s daily life easier.

Search and traversal work as if the data were already clean

With GraphAware Hume 3.0’s smart entity resolution mode, analysts exploring an Entity Group don’t need to think about the underlying grouping structure. They can search for and expand entities in the same way regardless of which modelling pattern sits underneath, without having to navigate through a group node to reach constituent records.

Grouping keeps the default view uncluttered without hiding anything

GraphAware Hume’s grouping feature collapses the records belonging to one resolved entity into a single logical node in the visualisation. An analyst sees one Robert Miller rather than four separate fragments, while still being able to expand the node to inspect the underlying source records.

Entity resolution -selection

Contradictions are visible, instead of getting silently overwritten

When an analyst expands a resolved entity, they don’t see one flattened answer. They see every constituent record, side by side, exactly as each source reported it. If two sources disagree, that disagreement is the finding, not a bug to be resolved.

Explainability is one right-click away

On a resolved entity, an analyst can invoke Senzing’s how/why action directly inside GraphAware Hume’s visualisation environment. It returns the exact attribute combinations and confidence scores behind the match, as a structured table, without requiring the analyst to leave their workflow or open a separate system. This puts the provenance and explainability discussed in post one directly into the investigation.

Senzing - why

Resolution changes get surfaced, not just stored

GraphAware Hume’s Orchestra workflows can trigger alerts when a monitored entity is attached to, or detached from, a resolved entity group. For instance, they can flag the moment a newly ingested record resolves to a person already linked to a sanctioned entity. Resolution stops happening silently in the background and becomes something an investigation can react to as it happens.

One filtering detail worth knowing: Senzing frequently produces single-record “entities,” cases where nothing else has matched yet. Left in the graph, these add volume without adding any resolution value. GraphAware Hume filters them out automatically, so what analysts actually see in their investigations is signal, not noise.

Why the combination is stronger than either piece alone

Senzing does the thing it’s purpose-built for extremely well: principle-based matching across large volumes of structured records, in real time, with a defensible audit trail behind every decision. That’s a hard problem, and not one you should set out to solve yourself when a mature engine already does it better.

But a resolution decision sitting in an engine’s output isn’t yet something an investigator can use. It has to become part of the connected picture: traceable back to its sources, explorable without extra cognitive overhead, respecting existing access boundaries, and visible enough that an analyst notices when it changes. That’s what a graph-powered intelligence analysis solution provides: provenance, access control, explainability, and the ability to reason across relationships once entities are resolved.

Senzing without an investigation layer like this produces accurate matches nobody can navigate. A graph without a dedicated resolution engine behind it stays fragmented, no matter how good the visualisation is. Together, they solve two different halves of the same problem: deciding what’s the same, and making that decision usable.

What’s next

We’ve covered how a purpose-built engine like Senzing resolves records, and how that resolution becomes part of a working entity-resolved graph in GraphAware Hume. But attribute matching, however sophisticated, can only work with what’s actually in the records. Two records can share almost nothing comparable: different names, different formats, no shared identifier at all, and still belong to the same person.

That’s not always a dead end. Sometimes the answer isn’t in the records themselves; it’s in the graph around them. A shared address three hops away. A pattern of connections that only makes sense if two “different” people are actually one. The graph doesn’t just store what an engine like Senzing has already resolved; it can start surfacing matches no attribute-based engine would ever catch on its own.

That’s graph-grounded entity resolution, and it’s where this series goes next.

If any of this raises questions about how entity resolution might work for your own organisation, get in touch. We’re happy to talk through where the gaps in your data might be hiding connections you haven’t made yet.


Meet the authors