Filter by label (via Path or Shape)



I’m still pretty new to Cayley. At this point, able to get quads in. Still getting my head around getting data out. I’m using the golang API. The shape or path interfaces, I understand, are the current best practice for this. (right?)

One thing I’m stuck on, getting quads or values out, filtered by label(s). I’m suspect it can be done, when I see in shape/path.go:

func HasLabels(from, via, nodes, labels Shape, rev bool) Shape

Can anyone provide an example of how to use this? It needs a Shape to produce a Shape. Chicken and egg to a beginner like me.

What I’d like to see an example of is… given the graph has several quads with the same subject, some of them labeled “one” and others labeled “two”… how can I iterate exclusively the quads labeled “one”, for that specific subject?

Thanks for any help!



Here’s something that I think works. I think it’s overly complicated, so I hope someone here eventually shows a better way!

  iri := quad.IRI("identifier") // the node we're interested in
  label := "one" // the label we're interested in

  subject := path.StartPath(qs, iri)
  object := subject.LabelContext(label).Out() // values (predicate info lost)
  predicate := object.InPredicates()          // get the predicate back
  predicate.Iterate(ctx).EachValue(nil, func(pred quad.Value) {
    log.Println("PREDICATE:", pred) // debug
    subject.LabelContext(label).Out(pred).Iterate(ctx).EachValue(nil, func(obj quad.Value) {
      // at last, we have both the predicate and the value assiciated with it
      log.Printf("QUAD: %s -- %s -- %s (%q)", iri, pred, obj, label) // debug

Query to extract edges directly using go

Yes, sorry, we need to expand docs for shapes.

The helper is a bit stricter than it should be, but the general idea is that it needs you to specify every shape manually (to have better control). Providing nil won’t work, because it will optimize the resulting query to nothing (no results).

If I understood correctly, you want to query quads with a specific subject, predicate, and label. Here is how to achieve this with shapes:

// you can add or remove filters here
quads := shape.Quads{
  {Dir: quad.Subject, Nodes: shape.Lookup{someNode}},
  {Dir: quad.Predicate, Nodes: shape.Lookup{somePred}},
  {Dir: quad.Label, Nodes: shape.Lookup{label1, label2}}, // logic for Lookup is OR
it := shape.BuildIterator(quads, qs) // gives a quad iterator

s := NodesFrom{Quads: quads, Dir: quad.Object}
it := shape.BuildIterator(s, qs) // gives only object nodes from those quads (like Out)

And if you want to Save something from the quad:

quads := shape.Quads{
  {Dir: quad.Predicate, Nodes: shape.Save{
     From: shape.AllNodes{},
     Tags: []string{"someTag"},

In general, if you see an helper in shapes that needs some argument that you don’t have, it’s most probably AllNodes{}. In rare cases it’s Quads{} (no filters = all quads).