Cypher query to create multiple nodes and relationships - nosql

I'm trying to write a Cypher query to create multiple nodes and relationships in one query. The documentation on using CREATE clauses in Cypher states that it's not possible to create multiple nodes of different types in a singular CREATE clause.
However it hints that I should be able to break it up into multiple CREATE's. A couple of similar answers I have read point to the same solution as well. I've tried doing this and keep getting the response error.
Error: If you create multiple elements, you can only create one of each.
Here is a brief outline of what I'm trying to do.
Create an item node.
Create multiple representation nodes.
Create a relationship between the created item node and an existing stack node.
Create multiple relationships between the created item node and the created representation nodes.
This is the query I'm currently using which attempts to break up all the individual parts of the CREATE process into individual steps.
START stack=node({stack})
CREATE (item {item})
CREATE (representations {representations})
CREATE (stack)-[:Item]->(item)
CREATE (item)-[:Representation]->(representations)
RETURN item, representations
I've tried several variations of the above query, including putting the creation of the item and representation nodes at the beginning of the query.
I would really appreciate any advice. I really don't want to resort to making multiple database calls if it can be avoided.

Is your representations a list ? Then you can only have that as the single create statement.
I assume Neo4j 1.9 from your syntax.
What you can do though is to use FOREACH
START stack=node({stack})
CREATE (item {item})
CREATE (stack)-[:Item]->(item)
FOREACH (r in {representations} :
CREATE (representation {r}), (item)-[:Representation]->(representation)
)
MATCH (item)-[:Representation]->(representations)
RETURN item, representations

Related

Gorm many to many find with condition

There are simply 3 such entities. My goal is to find resources using gorm. But I want to find it based on a certain condition. Exactly what I want is to find the resources containing the specific word in the name of the service. How should I use a preload and where()

How to ensure that only one item is added to janusgraph

Is there a way that I can ensure that any creation of a vertex in janusgraph with a given set of properties only results in one such vertex being created?
Right now, what I do is I traverse the graph and ensure that the number of vertices I find with particular properties is only one. For example:
val g = graph.traversal
val vertices = g.V().has("type", givenType).has("name", givenName).toList
if (vertices.size > 1) {
// the vertex is not unique, cannot add vertex
}
This can be done with the so called get or create traversal which is described in TinkerPop's Element Existence recipe and in the section Using coalesce to only add a vertex if it does not exist of the Practical Gremlin book.
For your example, this traversal would look like this:
g.V().has("type", givenType).has("name", givenName).
fold().
coalesce(unfold(),
addV("yourVertexLabel").
property("type", givenType).
property("name", givenName))
Note however, that it depends on the graph provider whether this is an atomic operation or not. In your case of JanusGraph, the existence check and the conditional vertex addition are executed with two different operations which can lead to a race condition when two threads execute this traversal at the same time in which case you can still end up with two vertices with these properties. So, you currently need to ensure that two threads can't execute this traversal for the same properties in parallel, e.g., with locks in your application.
I just published a blog post about exactly this topic: How to Avoid Doppelgängers in a Graph Database if you want to get more information about this topic in general. It also describes distributed locking as a way to implement locks for distributed systems and discusses possible improvements to better support upserts in JanusGraph in the future.

How to find nodes within ways in Overpass QL?

I have a query which returns a number of ways. I want to find nodes matching certain criteria which appear within those ways. Note that the nodes I'm interested in do not form part of the way itself, but do appear within the bounds of the way. Also, the ways do not all have corresponding areas, so using the area search doesn't work in all cases.
I've got a minimal example which finds way 95677318, and I want to be able to find node 1552949334:
(
way({{bbox}})["man_made"="lighthouse"];
)->.searchArea;
/*doesn't work:*/
/*node(area.searchArea)["seamark:name"];*/
/*recur down and find node directly, just for the purpose of this question*/
(
.searchArea;>;
node({{bbox}})["seamark:name"];
);
out;
(Try it on https://overpass-turbo.eu/s/EpV)
This feature is not yet available as of release 0.7.55. In case there's no corresponding area available on the Overpass server, this kind of query is simply not feasible.
See https://github.com/drolbr/Overpass-API/issues/77 for details.

Use filter to find sub-element of table in database (DBeaver)

I'm currently trying to list all Triggers available in a PostgreSQL database, regardless of the tables, using the DBeaver GUI.
What I would like to get looks like this:
https://ibb.co/dJZXCo
A result displaying only the Triggers category would be enough, I just want to quickly identify where the triggers are in my base.
To do so, I've tried to use global filters on the base itself, but it only filters table names.
I don't know if I can configure search depth so it includes inner elements of tables; or if there is a dedicated syntax to process the Triggers category in tables; or if the solution doesn't have anything to do with filtering.
There might be a very simple solution, but I can't seem to find it.
Thank you!

Perl: Quickly find object in list of objects - looking for a fitting datastructure

I am developing a program to sync users between to different LDAP Servers. I have two types of user groups: Master-Groups and Target-Groups (those are predefined in a config-file. There can be multiple Master and Targets per Group definition).
Users in Master-Groups missing in the Target-Groups shall be added to the Targets, Users in Target-Groups missing in Master-Groups shall be removed from the Targets.
The Users in those Groups are Objects themselves. My problem is as follows:
I loop through my availiable master groups and have to perform a quick lookup wheter a user is already part of a target-group. I am struggeling to pick the right datastructure to solve this problem. I tried using a hash, but quickly realized that hash-keys are stringyfied, so I cannot perform
if ( exists( $master_members->{$target_user_object} ) )
When using an array for storing the objects, everytime I have to check if a user object exists, I have to loop through the whole array which essentially kills performance.
How do I perfom a lookup if a specific object exists in a list of objects?
Kind Regards,
Yulivee
You're right that hash keys are stringified. You cannot use objects as keys. But a hash is the right data structure.
Instead of just letting Perl stringify your references, build your own serializer. That could be as simple as using the cn. Or a concatenation of all the fields of the object. Make a sub, put that in there, call that sub within your exist.
... if exists $master_members->{ my_serializer($target_user_object) };