Neo4jClient - Create index from within Neo4jClient? - neo4jclient

Is there a way to create an index from within Neo4jClient? I've done a raw query, but don't think that's the best option. My reason for doing so is in testing purposes where I need to drop/recreate databases to test performance of different designs.

You can do indexes like:
graphClient.Cypher
.Create("INDEX ON :Label(Property)")
.ExecuteWithoutResults();
and constraints like:
graphClient.Cypher
.CreateUniqueConstraint("identity", "property")
.ExecuteWithoutResults();
(originally from How to Create a Node with Neo4jClient in Neo4j v2?)

Related

Create relationship with properties using a query in Cypher

I would like to know if this is possible. I have a query that produces a nice report showing a relationship between two entities through two other nodes. There can be more than one path. I now want to create a direct relationship between those two nodes and count the number of paths and sum based upon data in the nodes in between. the report query is below.
match (bo:BuyerAgency)<-[:IS_FOR_BO]-(sol:Solicitation)-[:SELECTED]->(prop:Proposal)<-[:OWNS_BID]-(so:VendorOrg)
where sol.currStatus='Awarded'
return bo.AgencyName, count(sol.Number) as awards, so.orgName, sum(prop.finalPrice) as awardVolume;
What I want to do is similar to below which will not work.
match (bo:BuyerAgency)<-[:IS_FOR_BO]-(sol:Solicitation)-[:SELECTED]->(prop:Proposal)<-[:OWNS_BID]-(so:VendorOrg)
where sol.currStatus='Awarded'
create (bo)-[:HAS_AWARDED{awardCount: count(sol.Number), awardVolume: sum(prop.finalPrice)}]->(so);
If I remove the properties for the relationship, it works but want to add the properties without to much programing.
I am using the most recent version of Neo4j 3.2.
thanks
The problem here is you are trying to use count() and sum() functions in an invalid context. The below query should work:
match (bo:BuyerAgency)<-[:IS_FOR_BO]-(sol:Solicitation)-[:SELECTED]->(prop:Proposal)<-[:OWNS_BID]-(so:VendorOrg)
where sol.currStatus='Awarded'
with bo, so, count(sol.Number) as count_sol, sum(prop.finalPrice) as sum_finalPrice
create (bo)-[:HAS_AWARDED{awardCount: count_sol, awardVolume: sum_finalPrice}]->(so);
This query uses WITH to pass bo, so and the result of the aggregation functions count(sol.Number) and sum(prop.finalPrice) to the next context. After, these values are used to create the new relation between bo and so.

How to create a new relationship in Neo4j, starting from an existing one, using a Cypher query?

Is there a simple way to create a new relationship in Neo4j, starting from an existing one?
Starting from the actor-director-movie database used in the tutorials, what I would like to do is to get all the {(actor1),(actor2)} couples of nodes in the graph satisfying the relationships:
(actor1)-[:ACTED_IN]->(movie)<-[:ACTED_IN]-(actor2)
and use them to create a new relationship like:
(actor1)-[:ACTED_IN_THE_SAME_MOVIE_AS]-(actor2)
in whatever direction (I am interested in both directed and undirected graphs).
Is there a way to do this with a simple Cypher query?
Many thanks,
sTe
Using the sample movie dataset:
MATCH (actor1:Person)-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(actor2:Person)
WITH actor1, actor2
MERGE (actor1)-[:ACTED_IN_THE_SAME_MOVIE_AS]-(actor2)
I'd do that :
MATCH (actor1)-[:ACTED_IN]->()<-[:ACTED_IN]-(actor2)
CREATE UNIQUE (actor1)-[:ACTED_IN_THE_SAME_MOVIE_AS]-(actor2)
which is basically what you said. Relations are uni-directional (no way around), but the api (Cypher queries or Traversal) can read them both ways (so it doesn't really matter which way your create them in some cases).
To check if what you did is ok, you can run the following :
MATCH (actor1)-[:ACTED_IN_SAME_MOVIE]-(actor2)
RETURN actor1, actor2

How to use "MATCH.. CREATE UNIQUE.." with neography

I'm trying to write an importer script that will take a MySQL resultset and add nodes and relationships in my Neo4J DB. To simplify things, my resultset has the following fields:
application_id
amount
application_date
account_id
I want to create a node with Application label with the application_id, amount, application_date fields and another node with Account label with account_id field and a relationship between them.
My SQL query is from the applications table so I'm not afraid of dups there, but an account_id can appear more than once and I obviously don't want to create multiple nodes for that.
I'm using neography (but willing to switch if there is something simpler). What would be the best (easiest) way to achieve that?
My script will drop the database before it starts so no leftovers to take care of.
Should I create an index before and use create_unique_node?
I think I can do what I want in cypher using "MATCH .. CRAETE UNIQUE..", what's the equivalent of that in neography? I don't understand how index_name gets into the equation...
Should I or should I not define the constraint on Account?
Many thanks,
It's my first time with graph DBs so apologies if I miss a concept here..
From what you describe, it looks like you should use the constraints that come with Neo4j 2.0 : http://docs.neo4j.org/chunked/milestone/query-constraints.html#constraints-create-uniqueness-constraint
CREATE CONSTRAINT ON (account:ACCOUNT) ASSERT account.account_id IS UNIQUE
Then you can use the MATCH .. CREATE UNIQUE clauses for all your inserts. You can use neography to submit the cypher queries, see the examples here: https://github.com/maxdemarzi/neography/wiki/Scripts-and-queries

Possible to create an index on a label in py2neo?

I was wondering if it is possible to create an index on a label in py2neo? Like the Cypher: "CREATE INDEX ON :Person(name)"?
I think this is something that was added in Neo4j 2.0, so it might not be implemented in py2neo yet?
Thanks
Yes, you should be able to manage label indices from py2neo, take a look at the Schema chapter. I think py2neo generally wraps cypher queries, so I would think the methods for schema management are equivalent to the different cypher schema statements.
And you can always execute your own queries directly, so anything you can do in cypher you can do in py2neo.

Clone nodes and relationships with Cypher

Is it possible to clone arbitrary nodes and relationships in a single Cypher neo4j 2.0 query?
'Arbitrary' reads 'without specifying their labels and relationship types'. Something like:
MATCH (node1:NodeType)-[e]->(n)
CREATE (clone: labels(n)) set clone=n set clone.prop=1
CREATE (node1)-[e1:type(e)]->(clone) set e1=e set e1.prop=2
is not valid in Cypher, so one cannot simply get labels from one node or relationship and assign them to another, because labels are compiled into the query literally.
Sure, labels and relation types are important for MATCH and WHERE for producing effective query plan, but isn't CREATE making another case?
The easiest way to clone parts of a graph is to use the dump command in Neo4j shell. dump generates cypher create statements from your return clauses. The result of dump can be appied to the graph database to create clones.
Today, April 2022, I believe the best approach might be using an APOC procedure
I had a similar requirement and this worked for me.
MATCH (rootA:Root{name:'A'}),
(rootB:Root{name:'B'})
MATCH path = (rootA)-[:LINK*]->(node)
WITH rootA, rootB, collect(path) as paths
CALL apoc.refactor.cloneSubgraphFromPaths(paths, {
standinNodes:[[rootA, rootB]]
})
YIELD input, output, error
RETURN input, output, error

Resources