Tinkerpop Gremlin: Batching of multiple select query into one batch select query - gremlin

In Tinkerpop Gremlin,
I have two select query
g.V().has("id","foo").out().values("x").toList();
g.V().has("bar","foo").out().values("id").toList();
Now Can we club these query into one batched tinkerpop gremlin?
I tried
g.V().has("id","foo").out().values("x").union(__.V().has("bar","foo").out().values("id")).toList()
but this leads to a single list instead of two separate list. I want to extract the response of these two queries separately.

You could start your traversal with some dummy value and then union() the two traversals together:
gremlin> g.inject(0).union(V(1).out().fold(),V(2).in().fold())
==>[v[3],v[2],v[4]]
==>[v[1]]

Related

Generalized subqueries in Cypher 9

I have a graph in Neo4j, where all nodes and edges have a property p. With a cypher query as follows, I get a subgraph of the whole graph that fulfills several conditions on p for vertices and edges in general.
Q1
MATCH (n)
WHERE n.p ... // some conditions for nodes
OPTIONAL MATCH (n)-[r]-()
WHERE r.p ... // some conditions for relationships
RETURN n,r
Now I want to execute a second query Q2 on the resulting subgraph of the first query Q1. For example
Q2
MATCH (a:Person)-[:knows*5]-(b:Person)-[s:studiedAt]-(u:University),
(b)-[:owns]-(i:Business)
WHERE i.city = "Boston"
RETURN DISTINCT a.name, i.name, u.name
I do not want to apply the general conditions of Q1 for each vertex and edge in Q2. That complicates the query, loses the generalization, and needs path variables for variable paths like [:knows*5].
Is there a smarter way to execute a query Q2 on the result of a query Q1? Or is this impossible in Cypher because of its missing composability and the fact, that the result is always a table and never a graph?
It's not present directly in Cypher as far as I know, but if you are using Neo4j Enterprise, then you can use Neo4j Graph Data Science Library, to create named subgraphs, and then you can query those subgraphs. The disadvantage that comes with this approach is your subgraph won't be updated as the original graph gets updated. Please go through the following documentation, on how to create a subgraph:
Projecting a subgraph
Querying your subgraph

Gremlin OLAP traversal query error regarding local star-graph

I'm trying to execute an OLAP traversal on a query that needs to check if a vertex has a neighbour of certain type.
i keep getting
Local traversals may not traverse past the local star-graph on GraphComputer
my query looks something like:
g.V().hasLabel('label1').
where(_.out().hasLable('label2'))
I'm using the TraversalVertexProgram.
needless to say, when running the same query in oltp mode there is no problem
is there a way to execute such logic?
That is limitation of TinkerPop OLAP GraphComputer. It operate on 'star-graph' objects. The vertex and connected edges only. It uses message passing engine inside. So you have to rewrite you query.
Option 1: start from label2 and go t label1. This should return the same result
g.V().hasLabel('label2').in().hasLabel('label1')
Option2: try to use unique edge labels and check edge label instead
g.V().hasLabel('label1').where(_.outE('label1_label2'))

Create Vertex only if "from" and "to" vertex exists

I want to create 1000+ Edges in a single query.
Currently, I am using the AWS Neptune database and gremlin.net for creating it.
The issue I am facing is related to the speed. It took huge time because of HTTP requests.
So I am planning to combine all of my queries in a string and executing in a single shot.
_g.AddE("allow").From(_g.V().HasLabel('person').Has('name', 'name1')).To(_g.V().HasLabel('phone').Where(__.Out().Has('sensor', 'nfc'))).Next();
There are chances that the "To" (target) Vertex may not be available in the database. When it is the case this query fails as well. So I had to apply a check if that vertex exists before executing this query using hasNext().
So as of now its working fine, but when I am thinking of combining all 1000+ edge creation at once, is it possible to write a query which doesn't break if "To" (target) Vertex not found?
You should look at using the Element Existence pattern for each vertex as shown in the TinkerPop Recipes.
In your example you would replace this section of your query:
_g.V().HasLabel('person').Has('name', 'name1')
with something like this (I don't have a .NET environment to test the syntax):
__.V().Has('person', 'name', 'name1').Fold().
coalesce(__.Unfold(), __.AddV('person').Property('name', 'name1')
This will act as an Upsert and either return the existing vertex or add a new one with the name property. This same pattern can then be used on your To step to ensure that it exists before the edge is created as well.

Best way to limit edges to the same group of verices using Gremlin against Azure Cosmos db graph

I need to get vertices filtered by a specific predicate on the properties, and all the edges (with a particular label, and perhaps some predicate on the properties of an edge) existing between them.
This is for a Cosmos Azure Db graph, and the solution should be a single Gremlin query.
So far I am thinking of something along the lines of:
g.V().has('property1', value1).has('property2', value2).select('vertices')
.outE().as('edges').inV().has('property1', value1).has('property2', value2)
.select('vertices','edges')
Is there a better way to achieve this?
Given the description and your comment, this traversal should work for you:
g.V().has('property1', value1).has('property2', value2).
aggregate('v').
outE(). /* add edge filters here */
inV().where(within('v')).
path().
union(union(limit(local, 1),
tail (local, 1)).dedup().aggregate('vertices'),
range(local, 1, 2).aggregate('edges')).
cap('vertices','edges').next()

Azure Cosmos Graph DB Compound Conditional Query

Using Azure's Cosmos DB Graph Database I have a sample DB:Sample Graph Database. I am trying to expand a simple query into one that returns all the "Person" Nodes that have a "Skill Ratings" Node where MS_OFFICE=FAIL AND .NET=TRUE.
Current Query Thus Far:
ENGLISH DESCRIPTION: Find "Person Nodes" whose "Skill Ratings" Node match MS_OFFICE=FAIL
GREMLIN QUERY: g.V().hasLabel("Person").as("PersonNode")
.out("scored").as("SkillNode")
.has("skill_Name","MS_OFFICE")
.has("skill_Value","FAIL")
.select("PersonNode").by("Name")
To modify the existing query to include a conditional element, I was wondering if I am just missing a specific traversal step in the TinkerPop Documentation?
I think you just need something like this:
g.V().hasLabel("Person").
where(out("scored").
has("skill_name","MS_OFFICE").
has('skill_value","FAIL")).
values('name')

Resources