Search code examples
gremlintinkerpop

Extracting properties and meta-properties into JSON-like structure with Gremlin


My customer vertex has 4 properties and 2 meta-properties (each containing a list). The task is to return the customer data in a JSON structure. I was able to come up with this query:

g.V('customerId')
    .project('customer', 'addresses', 'accounts')
    .by(properties().not(hasLabel('addresses', 'accounts')).group().by(key()).by(value()))
    .by(properties('addresses').valueMap().fold())
    .by(properties('accounts').valueMap().fold())

which produces result

{
  "customer": {
    "firstName": "Carl",
    "middleName": "Friedrich",
    "lastName": "Gauss",
    "age": 77
  },
  "addresses": [
    {
      "streetName": "View",
      "streetNumber": "43",
    },
    {
      "streetName": "Market",
      "streetNumber": "11",
    }
  ],
  "accounts": [
    {
      "accountNumber": "1234"
    },
    {
      "accountNumber": "4321"
    }
  ]
}

What I actually need is a structure like this:

{
  "firstName": "Carl",
  "middleName": "Friedrich",
  "lastName": "Gauss",
  "age": 77,
  "addresses": [
    {
      "streetName": "View",
      "streetNumber": "43",
    },
    {
      "streetName": "Market",
      "streetNumber": "11",
    }
  ],
  "accounts": [
    {
      "accountNumber": "1234"
    },
    {
      "accountNumber": "4321"
    }
  ]
}

The closest I was able to get is this query:

g.V('customerId')
    .properties()
    .group()
    .by(key)
    .by(choose(hasLabel('addresses','accounts'), valueMap().fold(), value()))

which unfortunatelly groups address and account content so I can actually see only the last address/account:

{
  "firstName": "Carl",
  "middleName": "Friedrich",
  "lastName": "Gauss",
  "age": 77,
  "addresses": [
    {
      "streetName": "Market",
      "streetNumber": "11",
    }
  ],
  "accounts": [
    {
      "accountNumber": "4321"
    }
  ]
}

Is there a way to list all the meta-properties elements?


Solution

  • For the example above,

    If you add fold().unfold() it will take into account all the properties:

    g.V('c81e3753-1eaa-453b-85bc-818174de70c1')
        .properties()
        .group()
        .by(key)
        .by(fold().unfold().choose(hasLabel('addresses','accounts'), value().fold(), value()))