Improve Facets with Upsert Block

Ref: CREATE - Neo4j Cypher Manual

MATCH (a:Person),(b:Person)
WHERE a.name = 'A' AND b.name = 'B'
CREATE (a)-[r:RELTYPE { name: a.name + '<->' + b.name }]->(b)
RETURN type(r), r.name

This above is how Neo4J deals with their “Facet” / relationship proprieties. And in this case, the query makes a “concat” between the values of both nodes, on the same edge.

in Graphql +- would look like.

upsert {
  query {
  A as var(func: type(Person)) @filter(eq(name, "A")) { a as name }
  B as var(func: type(Person)) @filter(eq(name, "B")) { b as name }
}

  mutation {
    set {
      uid(A) <RELTYPE> uid(B) (name="val(a)+'<->'val(b)").
    }
  }
}

In this case, we need a “concatenate” inside the double quotes for values and pass the val properties.

Implicit vals

Also another ref: Improve Facets mutation handling · Issue #1996 · dgraph-io/dgraph · GitHub

If we have @facets(r as rating ...) in theory variables can catch the predicate name and the value recursively. So for Facets this would be nice. Cuz when it expands the val it will expand the attribute and value when using the variable in the mutation.

So instead of val(r)=val(r) we just val(r).

upsert {
  query {
        var(func: eq(email, "aman@dgraph.io")) {
          v as uid
          edge as someEdge @facets(r as rating, t as something, e as somethingElse)
        }
      }

  mutation {
    set {

      uid(v) <someEdge> uid(edge)
(weight=0.1, updated_at=2019-06-02T13:01:09, val(r), val(t), val(e)) .
#OR
(weight=0.1, updated_at=2019-06-02T13:01:09, rating=val(r), something=val(t), somethingElse=val(e)) .
    }
  }
}

I vote to always simplify it. The smaller and more direct the query is, the better.

Recurse value variable

upsert {
  query {
        var(func: eq(email, "aman@dgraph.io")) {
          v as uid
          edge as someEdge @facets(r as ...)
        }
      }

  mutation {
    set {

      uid(v) <someEdge> uid(edge) (
             val(r) # In this variable will enter all data we had previously. Recursively.
             weight=0.1,
             updated_at="2019-06-02T13:01:09",
             ) .

    }
  }
}

The three dots would be the operator (r as ...). It will copy and paste the previous values together with the new values.

In this case, “weight” and “updated_at” already exist and will be captured by the “Recursive Variable”. However, at the time of mutation, the new data will prevail.

Do we have an update on this RFC?

Nope, @ashishgoswami has done some work on this topic (facets), but no latest work was in this direction. And as ticket features are in low priority. I think this won’t be worked soon.

Is there some workaround to update the facets (add a new facets along with the existing ones) other than doing it in the client side?

Nope, not even the “Vanilla” way of doing it has this feature. I strongly believe that we should focus on that. Cuz facets are useful and several users use it.

One should collect all facets manually on the edge and on the fly do append the new value.

1 Like

Where are the tickets related to this?

It seems a bit bizzare that adding a facet to a predicate without loosing the old ones is in anyway complicated.

Also the theme seems to be known since Jan 2018: Improve Facets mutation handling - #12 by diggy