> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brussle.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Read a matcher's picks from the invoice

> A judgment on each invoice reads the payments a matcher picked for it, follows each pick as it moves, and is judged again only when its links change. Or count the matches, with no judgment on each invoice.

A judgment on each invoice can read the payments that a matcher picked for it: "do the payments matched to this invoice settle it in full?" The invoice follows the matcher's current picks, with no pipeline that copies them, and Brussle judges it again only when a pick to or from it changes.

The connection is a **link**: a relation whose `join` is the matcher's answer. See [documents a matcher linked](/concepts/relations#documents-a-matcher-linked). The examples read `settles`, the matcher from [match a payment to its invoice](/guides/entity-matching).

## Declare the link

```json theme={"theme":{"light":"css-variables","dark":"css-variables"}}
{
  "name": "invoice_settlement",
  "type": "bool",
  "applies_to": {"attributes.kind": "invoice"},
  "question": "Do the payments matched to this invoice settle it in full?",
  "context": {
    "fields": ["state.number", "state.amount", "state.due_at"],
    "related": {
      "matched_payments": {
        "match": {"attributes.kind": "payment", "attributes.status": "unmatched"},
        "join": {"theirs": "answers.settles.value", "mine": "id", "when": {"below": "unmatched"}},
        "window": "180d",
        "last_n": 20,
        "fields": ["state.amount", "state.received_at", "state.payer"],
        "aggregate": {"count": true, "sum": ["state.amount"]}
      }
    }
  },
  "engine": {"name": "jev", "version": "current"},
  "freshness": {"policy": "on_change"},
  "confirm": true
}
```

```mermaid theme={"theme":{"light":"css-variables","dark":"css-variables"}}
flowchart LR
  p1["payment<br/>settles: inv_2043"] -- "answers.settles.value" --> i["invoice inv_2043"]
  p2["payment<br/>settles: inv_2043"] --> i
  p3["payment<br/>settles: inv_2043<br/>unmatched: true"] -.-x i
  p4["payment<br/>settles: inv_2051"] -.-x i
  i:::judged
  classDef judged stroke-width:3px
```

`settles` picked `inv_2043` for two payments with their `unmatched` threshold `false`, so the invoice reads both. It does not read the payment whose pick crossed `unmatched`, or the one matched to a different invoice.

* **`when` is required.** A link exists only below one of the matcher's thresholds, so the invoice reads only the picks below it.
* **`match` repeats the matcher's `applies_to`.** `settles` must answer each payment the relation reads, as for any relation that reads answers.
* **`settles` keeps no old answers.** A judgment that reads blocks, and whose answers others read, needs `created_within: null` and no `where` in its fan-out scope, or a reader can keep reading an old answer. Limit `settles` with `applies_to` instead.
* **Other answers on the payments.** The relation can read the linked payments' answers from other judgments, such as a `fraud` threshold in `fields`. It reads nothing else of `settles`: its `value` is the invoice itself, and its threshold is the link's condition.
* **Booked payments.** To also read the payments you [recorded](/guides/entity-matching#record-the-match-the-reconciliation-shape) against the invoice, write the match to an attribute too, such as `attributes.settles`, and declare a second relation on it: `{"theirs": "attributes.settles", "mine": "id"}`. The link reads the payments that `settles` picked, and the second relation the ones you booked.

From the payment's side, a judgment can read the one invoice that `settles` picked. See [the document a match picked](/guides/referenced-document#the-document-a-match-picked).

The invoice judgment reads `settles`, so it is at least the second level of a [chain](/concepts/relations#at-most-three-levels-never-a-loop), whatever else it reads. An account judgment that reads the invoices' answers is the third, and a portfolio can read the account.

## Which payments link

A payment links to the invoice while all of these hold:

* it agrees with the relation's `match`;
* it has the same key as the invoice;
* the current answer of `settles` names the invoice, with `unmatched` `false`.

A `failed` answer keeps its last pick, as any answer a relation reads does. A link ends at once when the payment leaves `match` (booked, deleted or outside `applies_to`), when its key changes, when `settles` picks another invoice, or when you change the threshold. The reconciliation write ends the link, because the payment leaves `match`.

When a [fit with features](/guides/entity-matching#let-your-own-numbers-help-pick) changes a payment's pick, the link moves to the new invoice, and both invoices are judged again, billed.

## When the invoice is judged again

* **A pick moves.** When `settles` moves a payment from one invoice to another, Brussle judges both. When it starts or stops a link, Brussle judges that invoice. A new answer that keeps the same pick causes nothing.
* **A linked payment changes.** A write can change what the relation shows of the payment, whether it links, or its key. The invoice is `pending` from the moment Brussle acknowledges the write, and is judged again.
* **Another answer it reads changes.** A change to another judgment's answer on the payment judges again the invoice the payment links to now.
* **A threshold of `settles` changes.** You confirm it as for any threshold a reader names (see [changing a threshold a reader reads](/guides/roll-up-rules#changing-a-threshold-a-reader-reads)), and Brussle judges again each invoice whose links it moves.

Sometimes a linked payment's answer still has work to do, such as a block change waiting for its debounce. The invoice's evaluation then records `settles` as `child_pending` under `upstream`. An invoice deleted and created again with the same `id` reads the payments whose answers name that `id`, and is judged again when `settles` judges those payments again.

## What it costs

The invoice judgment is judged again for links that start, stop or switch (a switch judges two invoices), and for writes to linked payments that change what the relation shows.

A payment whose `escape_p` sits near the threshold can start and stop a link each time it is judged, with nothing changed. Keep the threshold away from where most of your `escape_p` values fall. The create response's [replay estimate](/guides/related-documents#the-replay-estimate) counts each write to a payment the relation reads as one re-judge, and says `"excludes": ["source_deletes"]` for payments deleted in the window.

## Limits and refused changes

* **`block_cap`.** The invoice reads at most the `block_cap` of `settles` from its block. When the block holds more, the invoice is not judged again: it keeps its last answer and reads `stale` (`limit_reached`) until the block is back within the cap or you raise it. It never reads a partial list.
* **No reference index.** A link does not use a reference index of its own.
* **`settles` stays readable.** While invoice judgments read through the link, Brussle refuses these changes to `settles` with `conflict`, naming the readers:
  * delete or deactivate it;
  * give it a fan-out scope, or a policy other than `on_change`;
  * remove the threshold that `when` names;
  * activate a version without `options.from`, or whose candidates share a different key attribute.
* **To change the key,** delete the invoice judgments, activate the new version of `settles`, and create the invoice judgments again.

## What a link count measures

A matcher picks at most one candidate for each judged document, from the `last_n` it reads: by default the newest in its block, or with [`relative`](/guides/tune-a-matcher#the-oldest-open-invoice) the ones created nearest to it. The number of documents linked to a candidate says how often it was read and picked. What that means depends on the two sides:

* **The same kind on both sides,** such as [duplicates](/guides/entity-matching#duplicates-within-one-kind-of-record) or complaints matched to complaints. Each document reads the newest `last_n` of its block, so the link count mostly measures how recent the candidate is, not how many similar records exist. To count similar records, use a [group](/guides/groups) or an aggregate over a shared key.
* **Different kinds, with few candidates that seldom change,** such as complaints matched to the service bulletins of one product. Each block holds no more than `last_n` candidates, so each judged document reads them all, unless `window` or `relative` removes some. The link count of a candidate is then the number of documents that picked it. Read it with `aggregate: {"count": true}` on the link.

## Count the matches without a link

To know only how many documents matched any candidate, not which, count them on the document they point to: the payments of an account that settled any invoice, or the complaints about a vehicle that matched any bulletin. Use a `count_where` on the matcher's value in a relation of the account's judgment:

```json theme={"theme":{"light":"css-variables","dark":"css-variables"}}
{"aggregate": {"count": true, "count_where": {"answers.settles.value": {"not": "none_of_the_above"}}}}
```

The count needs no link and no judgment on each invoice, so it adds no engine call for each invoice. It adds one level to the chain. A payment that changes from one invoice to another does not change the count. Keep the count as a [feature](/train/features), and the fit on your outcomes weighs it. See [count the matches of a matcher](/guides/roll-up-rules#count-the-matches-of-a-matcher).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.