wonderful world
wonderful world

Reputation: 11599

How to get all the nodes as a hierarchical tree with a Gremlin query?

The following is a complex family members relationships represented with nodes and edges.

  1. The member represented as person node
  2. The marriage node represent the marriage between two person nodes
  3. son_of and daughter_of connect a person to a marriage node.
  4. root_person is first generation
  5. john and Brenda are second generation
  6. mark is third generation
  7. mary is fourth generation
  8. john has an ex-wife and wife
  9. mark and his ex-wife mark_ex_wife are cousins. This is because mark's father and mark_ex_wife's mother are siblings.

My requirement is to get all the nodes in hierarchical tree format. Starting with the root_person, his son john and his wife and the daughter brenda' and her husband should be returned. Then the next generation and so on...

Please answer whether my requirement is achievable with this model, or modify this model to get all the nodes. The JSON with key and value returned by the CosmosDB data explorer is the start. I can then parse the JSON returned by the query to create a hierarchical tree of parents and children in a custom format which is more easy to understand and print out.

g.V().drop()
g.E().drop()
g.addV('person').property(id, 'root_person').property('name', 'Root Person').property('title', 'male')
g.addV('person').property(id, 'root_person_wife').property('name', 'root_person_wife').property('title', 'female')
g.addV('person').property(id, 'john').property('name', 'john').property('title', 'male')
g.addV('person').property(id, 'john_wife').property('name', 'john_wife').property('title', 'female')
g.addV('person').property(id, 'john_ex_wife').property('name', 'john_ex_wife').property('title', 'female')
g.addV('person').property(id, 'brenda').property('name', 'brenda').property('title', 'female')
g.addV('person').property(id, 'brenda_husband').property('name', 'brenda_husband').property('title', 'male')
g.addV('person').property(id, 'mark').property('name', 'mark').property('title', 'male')
g.addV('person').property(id, 'mark_ex_wife').property('name', 'mark_ex_wife').property('title', 'female')
g.addV('person').property(id, 'mark_wife').property('name', 'mark_wife').property('title', 'female')
g.addV('person').property(id, 'mary').property('name', 'mary').property('title', 'female')
g.addV('person').property(id, 'mary_husband').property('name', 'mary Husband').property('title', 'male')
g.addV('marriage').property(id, 'root_person-root_person_wife').property('marriage_name', 'root_person-root_person_wife')
g.addV('marriage').property(id, 'john-john_wife').property('marriage_name', 'john-john_wife')
g.addV('marriage').property(id, 'john-john_ex_wife').property('marriage_name', 'john-john_ex_wife')
g.addV('marriage').property(id, 'brenda-brenda_husband').property('marriage_name', 'brenda-brenda_husband')
g.addV('marriage').property(id, 'mark-mark_ex_wife').property('marriage_name', 'mark-mark_ex_wife')
g.addV('marriage').property(id, 'mark-mark_wife').property('marriage_name', 'mark-mark_wife')
g.addV('marriage').property(id, 'mary-mary_husband').property('marriage_name', 'mary-mary_husband')

g.V('root_person').addE('married_in').to(g.V('root_person-root_person_wife'))
g.V('root_person_wife').addE('married_in').to(g.V('root_person-root_person_wife'))
g.V('john').addE('married_in').to(g.V('john-john_wife'))
g.V('john_wife').addE('married_in').to(g.V('john-john_wife'))
g.V('john').addE('married_in').to(g.V('john-john_ex_wife'))
g.V('john_ex_wife').addE('married_in').to(g.V('john-john_ex_wife'))
g.V('brenda').addE('married_in').to(g.V('brenda-brenda_husband'))
g.V('brenda_husband').addE('married_in').to(g.V('brenda-brenda_husband'))
g.V('mark').addE('married_in').to(g.V('mark_#mark_wife'))
g.V('mark_wife').addE('married_in').to(g.V('mark-mark_wife'))
g.V('mark').addE('married_in').to(g.V('mark-mark_ex_wife'))
g.V('mark_ex_wife').addE('married_in').to(g.V('mark-mark_ex_wife'))
g.V('mary').addE('married_in').to(g.V('mary-mary_husband'))
g.V('mary_husband').addE('married_in').to(g.V('mary-mary_husband'))

g.V('john').addE('son_of').to(g.V('root_person-root_person_wife')).property('son_of', 'john--root_person-root_person_wife')
g.V('brenda').addE('daughter_of').to(g.V('root_person-root_person_wife')).property('daugter_of', 'brenda--root_person-root_person_wife')
g.V('mark').addE('son_of').to(g.V('john-john_wife')).property('son_of', 'mark--john-john_wife')
g.V('mark_ex_wife').addE('daughter_of').to(g.V('brenda-brenda_husband')).property('daugter_of', 'mark_ex_wife--brenda-brenda_husband')
g.V('mary').addE('daughter_of').to(g.V('mark-mark_wife')).property('daugter_of', 'mary--mark-mark_wife') }

UPDATE:

I tried the following query in my cosmosdb query explorer but it does not bring-in all the nodes.

g.V('root_person').repeat(out('married_in')).emit().repeat(__.in('son_of', 'daughter_of')).emit().tree()

The query produced the following json. You will notice that it stopped at the second generation.

[
  {
    "root_person": {
      "key": {
        "id": "root_person",
        "label": "person",
        "type": "vertex",
        "properties": {
          "name": [
            {
              "id": "f1e8327e-add4-454b-bbb2-6f076a29ea49",
              "value": "Root Person"
            }
          ],
          "title": [
            {
              "id": "42fc9c2b-b613-4011-9a0a-183d907a96ac",
              "value": "male"
            }
          ]
        }
      },
      "value": {
        "root_person-root_person_wife": {
          "key": {
            "id": "root_person-root_person_wife",
            "label": "marriage",
            "type": "vertex",
            "properties": {
              "marriage_name": [
                {
                  "id": "30f428a9-e657-4284-b59a-b836d9f04887",
                  "value": "root_person-root_person_wife"
                }
              ]
            }
          },
          "value": {
            "john": {
              "key": {
                "id": "john",
                "label": "person",
                "type": "vertex",
                "properties": {
                  "name": [
                    {
                      "id": "64e4653d-6298-479d-ba0f-eb3a9ede2383",
                      "value": "john"
                    }
                  ],
                  "title": [
                    {
                      "id": "b99dacb3-e38d-4da8-b087-42860d2b28c0",
                      "value": "male"
                    }
                  ]
                }
              },
              "value": {}
            },
            "brenda": {
              "key": {
                "id": "brenda",
                "label": "person",
                "type": "vertex",
                "properties": {
                  "name": [
                    {
                      "id": "1d88e8a5-7340-4b6d-a2b9-8b3c325e7bf6",
                      "value": "brenda"
                    }
                  ],
                  "title": [
                    {
                      "id": "9b856caa-0b84-413c-8229-8e2c1e0cb0d3",
                      "value": "female"
                    }
                  ]
                }
              },
              "value": {}
            }
          }
        }
      }
    }
  }
]

Upvotes: 2

Views: 1272

Answers (1)

Daniel Kuppitz
Daniel Kuppitz

Reputation: 10904

A tree will represent the vertices in the same hierarchy as they are stored in the graph. Thus, spouses will not appear at the same level in a tree. I might be wrong, but I think what you want is a list of people in each generation..?

gremlin> g.V("root_person").
           union(identity(),
                 out("married_in").in("married_in")).dedup().
           aggregate("x").
           group("m").
             by(constant(-1)).
             by(id).
           repeat(out("married_in").
                  union(__.in("married_in"),
                        __.in("daughter_of","son_of").
                           union(identity(), 
                                 out("married_in").in("married_in"))).dedup().
                  where(without("x")).
                  aggregate("x").
                  group("m").
                    by(loops()).
                    by(id)).
           cap("m").unfold().
           order(local).
             by(keys).
           select(values)
==>[root_person,root_person_wife]
==>[brenda,brenda_husband,john,john_wife,john_ex_wife]
==>[mark_ex_wife,mark,mark_wife]
==>[mary,mary_husband]

Upvotes: 2

Related Questions