First queries

If you have successfully completed all the previous steps in this chapter you have now created your first graph, congratulations! The graph should look exactly like Figure 7.

Figure 7: HelloSparksee complete graph
Figure 7: HelloSparksee complete graph

Although you have accomplished the main objective of this guide we encourage you to follow the final steps: querying the graph and the necessary procedure of closing your graph database.

Let’s propose a simple example that illustrates how to query a Sparksee graph database. For instance you may be interested in finding out who acted in movies directed by Woody Allen and also acted in movies directed by Sofia Coppola. We are able to establish the connection between these two excellent directors.

We could start by searching for the “Woody Allen” node using the FindObject method. However, as we have just created the graph we know that we already have that information in a variable called pWoody because we kept it when adding the node.

As we already have the “Woody Allen” node, our first query is to obtain the collection of movies directed by him. For each of his movies, there is an edge of type DIRECTS that starts from his node to a node of type MOVIE. To retrieve this information we will use the Neighbors method against the “Woody Allen” node through the edge DIRECTS. As we are only interested in the head (hence the movie) of this directed edge we truncate this retrieval to “Outgoing” only.

[Java]
// Get the movies directed by Woody Allen
Objects directedByWoody = g.neighbors(pWoody, directsType, EdgesDirection.Outgoing);
[C#]
// Get the movies directed by Woody Allen
Objects directedByWoody = g.Neighbors(pWoody, directsType, EdgesDirection.Outgoing);
[C++]
// Get the movies directed by Woody Allen
Objects *directedByWoody = g->Neighbors(pWoody, directsType, Outgoing);
[Python]
# Get the movies directed by Woody Allen
directed_by_woody = graph.neighbors(woody_people, directs_type, sparksee.EdgesDirection.OUTGOING)
[Objective-C]
// Get the movies directed by Woody Allen
STSObjects *directedByWoody = [g neighbors: pWoody etype: directsType dir: STSOutgoing];

The result of the query is an Objects class instance. It stores a collection of Sparksee object identifiers as a set; in this way we do not obtain duplicated elements.

Figure 8: Movies directed by Woody Allen
Figure 8: Movies directed by Woody Allen

Now that we have found all the movies directed by Woody Allen, we can use them to find the people that acted in them. To do so, we can use the Neighbors operation again, but from the collection of movies of Woody Allen and using the CAST edge type. In this case, we will use Any edge direction because it is not a directed edge.

All the Objects instances should be closed when no longer needed, therefore we can close the directedbyWoody collection just after retrieving its cast.

[Java]
// Get the cast of the movies directed by Woody Allen
Objects castDirectedByWoody = g.neighbors(directedByWoody, castType, EdgesDirection.Any);

// We don't need the directedByWoody collection anymore, so we should close it
directedByWoody.close();
[C#]
// Get the cast of the movies directed by Woody Allen
Objects castDirectedByWoody = g.Neighbors(directedByWoody, castType, EdgesDirection.Any);

// We don't need the directedByWoody collection anymore, so we should close it
directedByWoody.Close();
[C++]
// Get the cast of the movies directed by Woody Allen
Objects *castDirectedByWoody = g->Neighbors(directedByWoody, castType, Any);

// We don't need the directedByWoody collection anymore, so we should delete it
delete directedByWoody;
[Python]
# Get the cast of the movies directed by Woody Allen
cast_directed_by_woody = graph.neighbors(directed_by_woody, cast_type, sparksee.EdgesDirection.ANY)

# We don't need the directed_by_woody collection anymore, so we should close it
directed_by_woody.close()
[Objective-C]
// Get the cast of the movies directed by Woody Allen
STSObjects *castDirectedByWoody = [g neighborsWithObjects: directedByWoody etype: castType dir: STSAny];

// We don't need the directedByWoody collection anymore, so we should close it
[directedByWoody close];

We now have all the people that acted in movies directed by Woody Allen (Figure 9) but we only wanted to know who also acted in movies directed by Sofia Coppola.

Figure 9: Cast in movies by Woody Allen
Figure 9: Cast in movies by Woody Allen

To match the cast in movies directed by Woody Allen with the cast in movies directed by Sofia Coppola we have to repeat the same queries previously performed for Woody Allen: the first is the retrieval of movies of Sofia Coppola followed by the retrieval of the cast of each of her movies. The result is shown in Figure 10.

Figure 10: Movies and cast for Sofia Coppola
Figure 10: Movies and cast for Sofia Coppola
[Java]
// Get the movies directed by Sofia Coppola
Objects directedBySofia = g.neighbors(pSofia, directsType, EdgesDirection.Outgoing);

// Get the cast of the movies directed by Sofia Coppola
Objects castDirectedBySofia = g.neighbors(directedBySofia, castType, EdgesDirection.Any);

// We don't need the directedBySofia collection anymore, so we should close it
directedBySofia.close();
[C#]
// Get the movies directed by Sofia Coppola
Objects directedBySofia = g.Neighbors(pSofia, directsType, EdgesDirection.Outgoing);

// Get the cast of the movies directed by Sofia Coppola
Objects castDirectedBySofia = g.Neighbors(directedBySofia, castType, EdgesDirection.Any);

// We don't need the directedBySofia collection anymore, so we should close it
directedBySofia.Close();
[C++]
// Get the movies directed by Sofia Coppola
Objects *directedBySofia = g->Neighbors(pSofia, directsType, Outgoing);

// Get the cast of the movies directed by Sofia Coppola
Objects *castDirectedBySofia = g->Neighbors(directedBySofia, castType, Any);

// We don't need the directedBySofia collection anymore, so we should delete it
delete directedBySofia;
[Python]
# Get the movies directed by Sofia Coppola
directed_by_sofia = graph.neighbors(sofia_people, directs_type, sparksee.EdgesDirection.OUTGOING)

# Get the cast of the movies directed by Sofia Coppola
cast_directed_by_sofia = graph.neighbors(directed_by_sofia, cast_type, sparksee.EdgesDirection.ANY)

# We don't need the directed_by_sofia collection anymore, so we should close it
directed_by_sofia.close()
[Objective-C]
// Get the movies directed by Sofia Coppola
STSObjects *directedBySofia = [g neighbors: pSofia etype: directsType dir: STSOutgoing];

// Get the cast of the movies directed by Sofia Coppola
STSObjects *castDirectedBySofia = [g neighborsWithObjects: directedBySofia etype: castType dir: STSAny];

// We don't need the directedBySofia collection anymore, so we should close it
[directedBySofia close];

In the collections called castDirectedByWoody and castDirectedBySofia we now have all the cast in movies directed by each director respectively. But the objective of the query was to find out who acted in movies directed by both of them. To achieve this we only need to calculate the intersection of these two sets of PEOPLE nodes.

[Java]
// We want to know the people that acted in movies directed by Woody AND in movies directed by Sofia.
Objects castFromBoth = Objects.combineIntersection(castDirectedByWoody, castDirectedBySofia);

// We don't need the other collections anymore
castDirectedByWoody.close();
castDirectedBySofia.close();
[C#]
// We want to know the people that acted in movies directed by Woody AND in movies directed by Sofia.
Objects castFromBoth = Objects.CombineIntersection(castDirectedByWoody, castDirectedBySofia);

// We don't need the other collections anymore
castDirectedByWoody.Close();
castDirectedBySofia.Close();
[C++]
// We want to know the people that acted in movies directed by Woody AND in movies directed by Sofia.
Objects *castFromBoth = Objects::CombineIntersection(castDirectedByWoody, castDirectedBySofia);

// We don't need the other collections anymore
delete castDirectedByWoody;
delete castDirectedBySofia;
[Python]
# We want to know the people that acted in movies directed by Woody AND in movies directed by Sofia.
cast_from_both = sparksee.Objects.combine_intersection(cast_directed_by_woody, cast_directed_by_sofia)

# We don't need the other collections anymore
cast_directed_by_woody.close()
cast_directed_by_sofia.close()
[Objective-C]
// We want to know the people that acted in movies directed by Woody AND in movies directed by Sofia.
STSObjects *castFromBoth = [STSObjects combineIntersection: castDirectedByWoody objs2: castDirectedBySofia];

// We don't need the other collections anymore
[castDirectedByWoody close];
[castDirectedBySofia close];

Remember that you should close the Objects when you are not going to use them anymore.

We think we may have the result that we were looking for. But how do we check the information from that Objects collection? You must use ObjectsIterator that will traverse all the elements inside the set. With this iterator we can get all the node identifiers in the result (PEOPLE node identifiers), one by one. Then, for each one, we can get their attributes. We are only interested in the name of the actor.

Here you have it! Scarlett Johansson is the link between both directors.

Figure 11: Link between Woody Allen and Sofia Coppola
Figure 11: Link between Woody Allen and Sofia Coppola
[Java]
// Say hello to the people found
ObjectsIterator it = castFromBoth.iterator();
while (it.hasNext())
{
    long peopleOid = it.next();
    g.getAttribute(peopleOid, peopleNameType, value);
    System.out.println("Hello " + value.getString());
}
// The ObjectsIterator must be closed
it.close();

// The Objects must be closed
castFromBoth.close();
[C#]
// Say hello to the people found
ObjectsIterator it = castFromBoth.Iterator();
while (it.HasNext())
{
    long peopleOid = it.Next();
    g.GetAttribute(peopleOid, peopleNameType, value);
    System.Console.WriteLine("Hello " + value.GetString());
}
// The ObjectsIterator must be closed
it.Close();

// The Objects must be closed
castFromBoth.Close();
[C++]
// Say hello to the people found
ObjectsIterator *it = castFromBoth->Iterator();
while (it->HasNext())
{
    oid_t peopleOid = it->Next();
    g->GetAttribute(peopleOid, peopleNameType, *value);
    std::wcout << L"Hello " << value->GetString() << std::endl;
}
// The ObjectsIterator must be deleted
delete it;

// The Objects must be deleted
delete castFromBoth;
[Python]
# Say hello to the people found
for people_oid in cast_from_both:
    graph.get_attribute(people_oid, people_name_type, value)
    print "Hello ", value.get_string()

# The Objects must be closed
    cast_from_both.close()
[Objective-C]
// Say hello to the people found
STSObjectsIterator *it = [castFromBoth iterator];
while ([it hasNext])
{
    long long peopleOid = [it next];
    [g getAttributeInValue: peopleOid attr: peopleNameType value: value];
    NSLog(@"Hello %@\n", [value getString]);
}
// The ObjectsIterator must be closed
[it close];

// The Objects must be closed
[castFromBoth close];

Again we have reused the Value class instance to get the value of the NAME attribute.

Note that the ObjectsIterator should also be closed before closing the Objects collection.

Back to Index