MQL reference navigation

$inverseMatch

The $inverseMatch stage in the aggregation pipeline inverts the usual direction of a match. Where $match holds one query and tests it against many documents, $inverseMatch reads a query out of each document and tests it against one supplied input. A document survives the stage when the query it carries matches that input.

That makes it the stage for collections of stored queries — saved searches, alert rules, subscription filters, routing policies — where the question is not "which documents match this query" but "which stored queries match this document".

$inverseMatch is specific to DocumentDB and has no MongoDB equivalent.

Syntax

The stage takes the input to test in one of two forms. Either supply it inline with input:

{
  $inverseMatch: {
    path: <string>,
    input: <expression>,
    defaultResult: <boolean>
  }
}

Or read it from another collection with from and pipeline:

{
  $inverseMatch: {
    path: <string>,
    from: <string>,
    pipeline: [ <stage>, ... ],
    defaultResult: <boolean>
  }
}

Parameters

ParameterDescription
pathRequired. The dotted path at which each document stores its query. Omitting it fails with Path parameter is missing for the operator $inverseMatch.
inputThe document to test the stored queries against. Must be a constant value or a string path expression such as "$payload" — anything else fails with $inverseMatch expects 'input' to be a constant value or a string path expression. It has to resolve to a document or an array of documents. Mutually exclusive with from.
fromThe collection to read input documents from, as a string. Requires pipeline. Mutually exclusive with input.
pipelineRequired when from is set. The pipeline run against from to produce the input documents. Only $match, $project and $limit may appear in it.
defaultResultOptional boolean, default false. The result used for a document that has no value at path — false drops it, true keeps it.

Exactly one of input or from must be present. Any other key is rejected with Unrecognized parameter supplied to $inverseMatch: '<name>'.

Examples

The examples use an alerts collection, where each document stores the query that defines the alert:

[
  { "_id": 1, "name": "High value orders", "criteria": { "total": { "$gt": 500 } } },
  { "_id": 2, "name": "Electronics", "criteria": { "category": "electronics" } },
  { "_id": 3, "name": "Bulk orders", "criteria": { "quantity": { "$gte": 10 } } },
  { "_id": 4, "name": "Unfiltered" }
]

Example 1: Which stored queries match this document

Find the alerts that a single order would trigger:

db.alerts.aggregate([
  {
    $inverseMatch: {
      path: "criteria",
      input: { total: 750, category: "electronics", quantity: 2 }
    }
  },
  { $project: { name: 1 } }
])
[
  { "_id": 1, "name": "High value orders" },
  { "_id": 2, "name": "Electronics" }
]

Alert 3 is dropped because the order's quantity is below its threshold, and alert 4 because it has no criteria field at all — defaultResult is false by default.

Example 2: Keeping documents that store no query

Set defaultResult to true to treat a missing query as a match, which is how you model a catch-all rule:

db.alerts.aggregate([
  {
    $inverseMatch: {
      path: "criteria",
      input: { total: 750, category: "electronics", quantity: 2 },
      defaultResult: true
    }
  },
  { $project: { name: 1 } }
])
[
  { "_id": 1, "name": "High value orders" },
  { "_id": 2, "name": "Electronics" },
  { "_id": 4, "name": "Unfiltered" }
]

Example 3: Taking the input from another collection

Use from and pipeline to test the stored queries against a document held elsewhere, rather than one written into the stage:

db.alerts.aggregate([
  {
    $inverseMatch: {
      path: "criteria",
      from: "orders",
      pipeline: [
        { $match: { _id: 4001 } },
        { $project: { total: 1, category: 1, quantity: 1, _id: 0 } },
        { $limit: 1 }
      ]
    }
  },
  { $project: { name: 1 } }
])

The pipeline is restricted to $match, $project and $limit. Any other stage fails with:

<stage> is not allowed to be used within an $inverseMatch stage, only $match, $project or $limit are allowed

Behavior

  • The stored value must be a query document. If the value at path is present but is not a document, the stage errors rather than skipping the document.
  • A missing path is not an error. When a document has no value at path, the stage uses defaultResult — false unless you set it otherwise — so those documents are dropped silently by default.
  • input is an expression, not just a literal. A string is treated as a path expression, so input: "$payload" tests each stored query against that document's own payload field. To pass a literal document, write it inline as in the examples above.
  • input may be an array. An array of documents is accepted as well as a single document.

Related content

  • $match — the usual direction: one query, many documents.
  • $project — shape the surviving documents.
  • $limit — one of the three stages permitted inside pipeline.