2

I am looking for how to use $graphLookup and its match condition to return all nodes until a condition is met, including matches breaks the condition in the recursion stack. the first node that satisfies the condition in the recursion stack on each separate branch.

This should work for an arbitrary topology.

EDIT: as Asya highlights, it's the first time that the condition is satisfied on each branch, and not on the entire recursion stack.

Example (note: "_id" fields in docs are omitted for brevity):

Data:

[
  {
    "key": 1,
    "parent": null,
    "name": "tom"
  },
  {
    "key": 2,
    "parent": 1,
    "name": "tom"
  },
  {
    "key": 3,
    "parent": 2,
    "name": "jack"
  },
  {
    "key": 4,
    "parent": 3,
    "name": "jonny"
  },
  {
    "key": 5,
    "parent": 1,
    "name": "jack"
  },
  {
    "key": 6,
    "parent": 5,
    "name": "jack"
  }
]

Query:

db.collection.aggregate([
  {
    "$match": {
      "parent": null
    }
  },
  {
    "$graphLookup": {
      "from": "collection",
      "startWith": "$key",
      "connectFromField": "key",
      "connectToField": "parent",
      "as": "children",
      "restrictSearchWithMatch": {
        "name": "jack"
      },
      "matchType":"firstHitAlongEachBranch"      // made-up option
    }
  }
])

Desired result:

[
  {
    "children": [
      {
        "key": 2,
        "name": "tom",
        "parent": 1
      },
      {
        "key": 3,
        "parent": 2,
        "name": "jack"
      },
      {
        "key": 5,
        "parent": 1,
        "name": "jack"
      },
    ],
    "key": 1,
    "name": "tom",
    "parent": null
  }
]

The result returns only the first of the three nodes (as expected).

Thank you

C. Claudio
  • 177
  • 13
  • You say you want "first node that matches the condition" but if the condition is $ne:jack then isn't it just "Tom"? why is your sample output including "jack" (twice even)? – Asya Kamsky Jun 22 '22 at 11:53
  • You are right - the question should be "first node that breaks the condition" - amending, thanks – C. Claudio Jun 22 '22 at 11:55
  • and it's not just first one that breaks it - you want first one that breaks it along each "branch" - $graphLookup goes breadth-first so it doesn't go "down" each branch first, and it looks like that's what you're looking for? – Asya Kamsky Jun 22 '22 at 15:31
  • Yes - the first break along each branch, but keep lookin on the others. In other words, does not break the recursion globally of the entire tree. Alternatively, it can be seen as searching until a condition is met - in this case name=="jack" (on each branch). – C. Claudio Jun 22 '22 at 17:59
  • There is no such functionality via $graphLookup – Asya Kamsky Jun 22 '22 at 20:26

1 Answers1

0

Apparently it's not possible to date.

There's an open Jira for it.

C. Claudio
  • 177
  • 13
  • That ticket is not exactly for what you are asking for. It's for stopping all traversal once a particular condition is met. There is no concept of doing different levels of traversal along different "branches" depending on condition - $graphLookup is going breadth first. – Asya Kamsky Jun 22 '22 at 20:28