Popular New Releases in Neo4j
janusgraph
0.6.1
neo
v3.2.1
RedisGraph
v2.8.11
neo4j-apoc-procedures
4.4.0.3
py2neo
Py2neo 2021.1.3
Popular Libraries in Neo4j
by neo4j java
9857 NOASSERTION
Graphs for Everyone
by JanusGraph java
4397 NOASSERTION
JanusGraph: an open-source, distributed graph database
by neo-project csharp
3376 MIT
NEO Smart Economy
by RedisGraph c
1595 NOASSERTION
A graph database as a Redis module
by apache java
1495 Apache-2.0
Apache TinkerPop - a graph computing framework
by neo4j-contrib java
1455 Apache-2.0
Awesome Procedures On Cypher for Neo4j - codenamed "apoc" If you like it, please ★ above ⇧
by neo4jrb ruby
1347 MIT
An active model wrapper for the Neo4j Graph Database for Ruby.
by lemonhu python
1248 MIT
利用网络上公开的数据构建一个小型的证券知识图谱/知识库
by technige python
1003 Apache-2.0
Py2neo is a comprehensive toolkit for working with Neo4j from within Python applications or from the command line.
Trending New libraries in Neo4j
by apache c
551 Apache-2.0
Graph database optimized for fast analysis and real-time data processing. It is provided as an extension to PostgreSQL.
by simon824 java
323
分布式图数据库 JanusGraph 中文社区,关于 JanusGraph 的一切
by neo4j typescript
306
A GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations.
by graphikDB go
295 Apache-2.0
Graphik is a Backend as a Service implemented as an identity-aware document & graph database with support for gRPC and graphQL
by wh1t3p1g java
254 Apache-2.0
A CAT called tabby ( Code Analysis Tool )
by danitseitlin typescript
161 Apache-2.0
A Software development kit for easier connection and execution of Redis Modules commands.
by umitkaanusta python
160 MIT
Play detective on Reddit: Discover political disinformation campaigns, secret influencers and more
by nielsdejong typescript
156 Apache-2.0
NeoDash - Neo4j Dashboard Builder
by ArcadeData javascript
152 Apache-2.0
ArcadeDB Multi-Model Database, one DBMS that supports SQL, Cypher, Gremlin, HTTP/JSON, MongoDB and Redis. ArcadeDB is a conceptual fork of OrientDB, the first Multi-Model DBMS.
Top Authors in Neo4j
1
40 Libraries
1143
2
35 Libraries
5906
3
33 Libraries
1729
4
26 Libraries
1519
5
24 Libraries
1156
6
19 Libraries
887
7
17 Libraries
224
8
16 Libraries
1662
9
14 Libraries
13953
10
13 Libraries
447
1
40 Libraries
1143
2
35 Libraries
5906
3
33 Libraries
1729
4
26 Libraries
1519
5
24 Libraries
1156
6
19 Libraries
887
7
17 Libraries
224
8
16 Libraries
1662
9
14 Libraries
13953
10
13 Libraries
447
Trending Kits in Neo4j
No Trending Kits are available at this moment for Neo4j
Trending Discussions on Neo4j
'Session' object has no attribute 'session'
Returning sum of specific node property values Neo4j
spring-data-neo4j v6: No converter found capable of converting from type [MyDTO] to type [org.neo4j.driver.Value]
Gremlin: Return new edges created in a query without saving them (equivalent to APOC vRelationship)
FIlter the list with a condition in Neo4J
Can't load CSV from Drive to Neo4j
Is it possible to connect to AuraDB with neomodel?
GraphQL Custom directive enforcing value restrictions
Is neo4j 3.5 impacted by CVE-2021-44228?
Neo4j: Get nodes that are at least related with some items of a list
QUESTION
'Session' object has no attribute 'session'
Asked 2022-Apr-05 at 07:201import neo4j
2import sys
3import uuid
4
5from neo4j import GraphDatabase
6
7
8def create_population_point(tx, _point, _uuid, _tl, _tr, _ll, _lr, _band):
9 print("Add a record block A")
10 tx.run("CREATE (n:Population_Point
11 {point:$point,uuid:$uuid,TL:$tl,TR:$tr,BL:$bl,BR:$br,Band_1:$band}),"
12 "point=_point,uuid=_uuid,tl=_tl,tr=_tr,ll=_ll,lr=_lr,band=_band")
13
14
15def main():
16uri = "neo4j://localhost:7687"
17username = "neo4j"
18password = "P@ssword2"
19
20databaseConnection = GraphDatabase.driver(uri, auth=(username, password))
21databaseSession = databaseConnection.session()
22print("Connection established")
23print("Variables assigned values")
24_point = "D007_S001_T001"
25_uuid = uuid.uuid4()
26_tl = "28.27291"
27_tr = "-81.65765"
28_ll = "28.27291"
29_lr = "-81.65765"
30_band = "455"
31print("Ready to execute")
32with databaseSession.session() as session:
33 result = session.write_transaction(create_population_point, _point, _uuid, _tl, _tr, _ll,
34 _lr, _band)
35databaseConnection.close()
36print("Connection closed")
37
38
39if __name__ == "__main__":
40 main()
41
This is the line that is throwing the error
with databaseSession.session() as session:
running python 3.10.4
ANSWER
Answered 2022-Apr-05 at 07:20First you create
1import neo4j
2import sys
3import uuid
4
5from neo4j import GraphDatabase
6
7
8def create_population_point(tx, _point, _uuid, _tl, _tr, _ll, _lr, _band):
9 print("Add a record block A")
10 tx.run("CREATE (n:Population_Point
11 {point:$point,uuid:$uuid,TL:$tl,TR:$tr,BL:$bl,BR:$br,Band_1:$band}),"
12 "point=_point,uuid=_uuid,tl=_tl,tr=_tr,ll=_ll,lr=_lr,band=_band")
13
14
15def main():
16uri = "neo4j://localhost:7687"
17username = "neo4j"
18password = "P@ssword2"
19
20databaseConnection = GraphDatabase.driver(uri, auth=(username, password))
21databaseSession = databaseConnection.session()
22print("Connection established")
23print("Variables assigned values")
24_point = "D007_S001_T001"
25_uuid = uuid.uuid4()
26_tl = "28.27291"
27_tr = "-81.65765"
28_ll = "28.27291"
29_lr = "-81.65765"
30_band = "455"
31print("Ready to execute")
32with databaseSession.session() as session:
33 result = session.write_transaction(create_population_point, _point, _uuid, _tl, _tr, _ll,
34 _lr, _band)
35databaseConnection.close()
36print("Connection closed")
37
38
39if __name__ == "__main__":
40 main()
41databaseSession = databaseConnection.session()
42
next you use
1import neo4j
2import sys
3import uuid
4
5from neo4j import GraphDatabase
6
7
8def create_population_point(tx, _point, _uuid, _tl, _tr, _ll, _lr, _band):
9 print("Add a record block A")
10 tx.run("CREATE (n:Population_Point
11 {point:$point,uuid:$uuid,TL:$tl,TR:$tr,BL:$bl,BR:$br,Band_1:$band}),"
12 "point=_point,uuid=_uuid,tl=_tl,tr=_tr,ll=_ll,lr=_lr,band=_band")
13
14
15def main():
16uri = "neo4j://localhost:7687"
17username = "neo4j"
18password = "P@ssword2"
19
20databaseConnection = GraphDatabase.driver(uri, auth=(username, password))
21databaseSession = databaseConnection.session()
22print("Connection established")
23print("Variables assigned values")
24_point = "D007_S001_T001"
25_uuid = uuid.uuid4()
26_tl = "28.27291"
27_tr = "-81.65765"
28_ll = "28.27291"
29_lr = "-81.65765"
30_band = "455"
31print("Ready to execute")
32with databaseSession.session() as session:
33 result = session.write_transaction(create_population_point, _point, _uuid, _tl, _tr, _ll,
34 _lr, _band)
35databaseConnection.close()
36print("Connection closed")
37
38
39if __name__ == "__main__":
40 main()
41databaseSession = databaseConnection.session()
42with databaseSession.session() as session:
43
so finally you try to use
1import neo4j
2import sys
3import uuid
4
5from neo4j import GraphDatabase
6
7
8def create_population_point(tx, _point, _uuid, _tl, _tr, _ll, _lr, _band):
9 print("Add a record block A")
10 tx.run("CREATE (n:Population_Point
11 {point:$point,uuid:$uuid,TL:$tl,TR:$tr,BL:$bl,BR:$br,Band_1:$band}),"
12 "point=_point,uuid=_uuid,tl=_tl,tr=_tr,ll=_ll,lr=_lr,band=_band")
13
14
15def main():
16uri = "neo4j://localhost:7687"
17username = "neo4j"
18password = "P@ssword2"
19
20databaseConnection = GraphDatabase.driver(uri, auth=(username, password))
21databaseSession = databaseConnection.session()
22print("Connection established")
23print("Variables assigned values")
24_point = "D007_S001_T001"
25_uuid = uuid.uuid4()
26_tl = "28.27291"
27_tr = "-81.65765"
28_ll = "28.27291"
29_lr = "-81.65765"
30_band = "455"
31print("Ready to execute")
32with databaseSession.session() as session:
33 result = session.write_transaction(create_population_point, _point, _uuid, _tl, _tr, _ll,
34 _lr, _band)
35databaseConnection.close()
36print("Connection closed")
37
38
39if __name__ == "__main__":
40 main()
41databaseSession = databaseConnection.session()
42with databaseSession.session() as session:
43databaseConnection.session().session()
44
and this is wrong.
You could use directly
1import neo4j
2import sys
3import uuid
4
5from neo4j import GraphDatabase
6
7
8def create_population_point(tx, _point, _uuid, _tl, _tr, _ll, _lr, _band):
9 print("Add a record block A")
10 tx.run("CREATE (n:Population_Point
11 {point:$point,uuid:$uuid,TL:$tl,TR:$tr,BL:$bl,BR:$br,Band_1:$band}),"
12 "point=_point,uuid=_uuid,tl=_tl,tr=_tr,ll=_ll,lr=_lr,band=_band")
13
14
15def main():
16uri = "neo4j://localhost:7687"
17username = "neo4j"
18password = "P@ssword2"
19
20databaseConnection = GraphDatabase.driver(uri, auth=(username, password))
21databaseSession = databaseConnection.session()
22print("Connection established")
23print("Variables assigned values")
24_point = "D007_S001_T001"
25_uuid = uuid.uuid4()
26_tl = "28.27291"
27_tr = "-81.65765"
28_ll = "28.27291"
29_lr = "-81.65765"
30_band = "455"
31print("Ready to execute")
32with databaseSession.session() as session:
33 result = session.write_transaction(create_population_point, _point, _uuid, _tl, _tr, _ll,
34 _lr, _band)
35databaseConnection.close()
36print("Connection closed")
37
38
39if __name__ == "__main__":
40 main()
41databaseSession = databaseConnection.session()
42with databaseSession.session() as session:
43databaseConnection.session().session()
44result = databaseSession.write_transaction(..)
45
or use databaseConnection
instead of databaseSession
in
1import neo4j
2import sys
3import uuid
4
5from neo4j import GraphDatabase
6
7
8def create_population_point(tx, _point, _uuid, _tl, _tr, _ll, _lr, _band):
9 print("Add a record block A")
10 tx.run("CREATE (n:Population_Point
11 {point:$point,uuid:$uuid,TL:$tl,TR:$tr,BL:$bl,BR:$br,Band_1:$band}),"
12 "point=_point,uuid=_uuid,tl=_tl,tr=_tr,ll=_ll,lr=_lr,band=_band")
13
14
15def main():
16uri = "neo4j://localhost:7687"
17username = "neo4j"
18password = "P@ssword2"
19
20databaseConnection = GraphDatabase.driver(uri, auth=(username, password))
21databaseSession = databaseConnection.session()
22print("Connection established")
23print("Variables assigned values")
24_point = "D007_S001_T001"
25_uuid = uuid.uuid4()
26_tl = "28.27291"
27_tr = "-81.65765"
28_ll = "28.27291"
29_lr = "-81.65765"
30_band = "455"
31print("Ready to execute")
32with databaseSession.session() as session:
33 result = session.write_transaction(create_population_point, _point, _uuid, _tl, _tr, _ll,
34 _lr, _band)
35databaseConnection.close()
36print("Connection closed")
37
38
39if __name__ == "__main__":
40 main()
41databaseSession = databaseConnection.session()
42with databaseSession.session() as session:
43databaseConnection.session().session()
44result = databaseSession.write_transaction(..)
45with databaseConnection.session() as session:
46 result = session.write_transaction(..)
47
(and remove databaseSession = databaseConnection.session()
because you don't use it)
QUESTION
Returning sum of specific node property values Neo4j
Asked 2022-Mar-25 at 08:15I have the same types of nodes in a Neo4j graph. I want to return node value sums. Below is an example graph:
I want to return them in such a way that node values (val
s) are summed w.r.t alias
and name
fields.
1[
2{"name": "a", "val": 120},
3{"name": "b", "val": 60}
4]
5
The first object summed nodes with name
value x
, y
, and a
because x
and y
had an alias field with value a
.
Update:
Indeed, val
property in the nodes represents number of RELATED_TO
relationships that a node has. I wanted to abstract that for simplifying the question. The real scheme is as shown below. Every white node has several RELATED_TO
relationships to green nodes. How can I map the number of such relationships to terminal nodes (summing val
fields)?
ANSWER
Answered 2022-Mar-25 at 07:10this should do it
1[
2{"name": "a", "val": 120},
3{"name": "b", "val": 60}
4]
5MATCH (n)
6RETURN COALESCE(n.alias, n.name) AS name, sum(n.val) AS val
7
QUESTION
spring-data-neo4j v6: No converter found capable of converting from type [MyDTO] to type [org.neo4j.driver.Value]
Asked 2022-Mar-16 at 17:26Situation
I'm migrating a kotlin spring data neo4j application from spring-data-neo4j
version 5.2.0.RELEASE
to version 6.0.11
.
The original application has several Repository interfaces with custom queries which take some DTO as a parameter, and use the various DTO fields to construct the query. All those types of queries currently fail with
1org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [MyDTO] to type [org.neo4j.driver.Value]
2
The reference documentation for spring-data-neo4j v6 only provides examples where parameters passed to custom query methods of a @Repository
interface are of the same type as the @Node
class associated with that repository. The documentation does not explicitly state that only parameters of the Node class are allowed.
Question
Is there any way to pass an arbitrary DTO (not being a @Node
class) to a custom query method in a @Repository
interface in spring-data-neo4j v6 like it was possible in v5?
Example node entity
1org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [MyDTO] to type [org.neo4j.driver.Value]
2@Node
3data class MyEntity(
4 @Id
5 val attr1: String,
6 val attr2: String,
7 val attr3: String
8)
9
Example DTO
1org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [MyDTO] to type [org.neo4j.driver.Value]
2@Node
3data class MyEntity(
4 @Id
5 val attr1: String,
6 val attr2: String,
7 val attr3: String
8)
9data class MyDTO(
10 val field1: String,
11 val field2: String
12)
13
Example Repository interface
1org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [MyDTO] to type [org.neo4j.driver.Value]
2@Node
3data class MyEntity(
4 @Id
5 val attr1: String,
6 val attr2: String,
7 val attr3: String
8)
9data class MyDTO(
10 val field1: String,
11 val field2: String
12)
13@Repository
14interface MyRepository : PagingAndSortingRepository<MyEntity, String> {
15
16 // ConverterNotFoundException is thrown when this method is called
17 @Query("MATCH (e:MyEntity {attr1: {0}.field1}) " +
18 "CREATE (e)-[l:LINK]->(n:OtherEntity {attr2: {0}.field2))")
19 fun doSomethingWithDto(dto: MyDTO)
20}
21
Annotate DTO as if it were a Node entity
Based on the following found in the reference docs https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#custom-queries.parameters
Mapped entities (everything with a @Node) passed as parameter to a function that is annotated with a custom query will be turned into a nested map.
1org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [MyDTO] to type [org.neo4j.driver.Value]
2@Node
3data class MyEntity(
4 @Id
5 val attr1: String,
6 val attr2: String,
7 val attr3: String
8)
9data class MyDTO(
10 val field1: String,
11 val field2: String
12)
13@Repository
14interface MyRepository : PagingAndSortingRepository<MyEntity, String> {
15
16 // ConverterNotFoundException is thrown when this method is called
17 @Query("MATCH (e:MyEntity {attr1: {0}.field1}) " +
18 "CREATE (e)-[l:LINK]->(n:OtherEntity {attr2: {0}.field2))")
19 fun doSomethingWithDto(dto: MyDTO)
20}
21@Node
22data class MyDTO(
23 @Id
24 val field1: String,
25 val field2: String
26)
27
Replace {0}
with $0
in custom query
Based on the following found in the reference docs https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#custom-queries.parameters
You do this exactly the same way as in a standard Cypher query issued in the Neo4j Browser or the Cypher-Shell, with the $ syntax (from Neo4j 4.0 on upwards, the old {foo} syntax for Cypher parameters has been removed from the database).
...
[In the given listing] we are referring to the parameter by its name. You can also use $0 etc. instead.
1org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [MyDTO] to type [org.neo4j.driver.Value]
2@Node
3data class MyEntity(
4 @Id
5 val attr1: String,
6 val attr2: String,
7 val attr3: String
8)
9data class MyDTO(
10 val field1: String,
11 val field2: String
12)
13@Repository
14interface MyRepository : PagingAndSortingRepository<MyEntity, String> {
15
16 // ConverterNotFoundException is thrown when this method is called
17 @Query("MATCH (e:MyEntity {attr1: {0}.field1}) " +
18 "CREATE (e)-[l:LINK]->(n:OtherEntity {attr2: {0}.field2))")
19 fun doSomethingWithDto(dto: MyDTO)
20}
21@Node
22data class MyDTO(
23 @Id
24 val field1: String,
25 val field2: String
26)
27@Repository
28interface MyRepository : PagingAndSortingRepository<MyEntity, String> {
29
30 // ConverterNotFoundException is thrown when this method is called
31 @Query("MATCH (e:MyEntity {attr1: $0.field1}) " +
32 "CREATE (e)-[l:LINK]->(n:OtherEntity {attr2: $0.field2))")
33 fun doSomethingWithDto(dto: MyDTO)
34}
35
spring-boot-starter
:v2.4.10
spring-data-neo4j
:v6.0.12
neo4j-java-driver
:v4.1.4
Neo4j server version
:v3.5.29
ANSWER
Answered 2021-Aug-23 at 21:03RTFM Custom conversions ...
Found the solution myself. Hopefully someone else may benefit from this as well.
SolutionCreate a custom converter
1org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [MyDTO] to type [org.neo4j.driver.Value]
2@Node
3data class MyEntity(
4 @Id
5 val attr1: String,
6 val attr2: String,
7 val attr3: String
8)
9data class MyDTO(
10 val field1: String,
11 val field2: String
12)
13@Repository
14interface MyRepository : PagingAndSortingRepository<MyEntity, String> {
15
16 // ConverterNotFoundException is thrown when this method is called
17 @Query("MATCH (e:MyEntity {attr1: {0}.field1}) " +
18 "CREATE (e)-[l:LINK]->(n:OtherEntity {attr2: {0}.field2))")
19 fun doSomethingWithDto(dto: MyDTO)
20}
21@Node
22data class MyDTO(
23 @Id
24 val field1: String,
25 val field2: String
26)
27@Repository
28interface MyRepository : PagingAndSortingRepository<MyEntity, String> {
29
30 // ConverterNotFoundException is thrown when this method is called
31 @Query("MATCH (e:MyEntity {attr1: $0.field1}) " +
32 "CREATE (e)-[l:LINK]->(n:OtherEntity {attr2: $0.field2))")
33 fun doSomethingWithDto(dto: MyDTO)
34}
35import mypackage.model.*
36import com.fasterxml.jackson.core.type.TypeReference
37import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
38import org.neo4j.driver.Value
39import org.neo4j.driver.Values
40import org.springframework.core.convert.TypeDescriptor
41import org.springframework.core.convert.converter.GenericConverter
42import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair
43import java.util.HashSet
44
45class DtoToNeo4jValueConverter : GenericConverter {
46 override fun getConvertibleTypes(): Set<ConvertiblePair>? {
47 val convertiblePairs: MutableSet<ConvertiblePair> = HashSet()
48 convertiblePairs.add(ConvertiblePair(MyDTO::class.java, Value::class.java))
49 return convertiblePairs
50 }
51
52 override fun convert(source: Any?, sourceType: TypeDescriptor, targetType: TypeDescriptor?): Any? {
53 return if (MyDTO::class.java.isAssignableFrom(sourceType.type)) {
54 // generic way of converting an object into a map
55 val dataclassAsMap = jacksonObjectMapper().convertValue(source as MyDTO, object :
56 TypeReference<Map<String, Any>>() {})
57 Values.value(dataclassAsMap)
58 } else null
59 }
60}
61
Register custom converter in config
1org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [MyDTO] to type [org.neo4j.driver.Value]
2@Node
3data class MyEntity(
4 @Id
5 val attr1: String,
6 val attr2: String,
7 val attr3: String
8)
9data class MyDTO(
10 val field1: String,
11 val field2: String
12)
13@Repository
14interface MyRepository : PagingAndSortingRepository<MyEntity, String> {
15
16 // ConverterNotFoundException is thrown when this method is called
17 @Query("MATCH (e:MyEntity {attr1: {0}.field1}) " +
18 "CREATE (e)-[l:LINK]->(n:OtherEntity {attr2: {0}.field2))")
19 fun doSomethingWithDto(dto: MyDTO)
20}
21@Node
22data class MyDTO(
23 @Id
24 val field1: String,
25 val field2: String
26)
27@Repository
28interface MyRepository : PagingAndSortingRepository<MyEntity, String> {
29
30 // ConverterNotFoundException is thrown when this method is called
31 @Query("MATCH (e:MyEntity {attr1: $0.field1}) " +
32 "CREATE (e)-[l:LINK]->(n:OtherEntity {attr2: $0.field2))")
33 fun doSomethingWithDto(dto: MyDTO)
34}
35import mypackage.model.*
36import com.fasterxml.jackson.core.type.TypeReference
37import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
38import org.neo4j.driver.Value
39import org.neo4j.driver.Values
40import org.springframework.core.convert.TypeDescriptor
41import org.springframework.core.convert.converter.GenericConverter
42import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair
43import java.util.HashSet
44
45class DtoToNeo4jValueConverter : GenericConverter {
46 override fun getConvertibleTypes(): Set<ConvertiblePair>? {
47 val convertiblePairs: MutableSet<ConvertiblePair> = HashSet()
48 convertiblePairs.add(ConvertiblePair(MyDTO::class.java, Value::class.java))
49 return convertiblePairs
50 }
51
52 override fun convert(source: Any?, sourceType: TypeDescriptor, targetType: TypeDescriptor?): Any? {
53 return if (MyDTO::class.java.isAssignableFrom(sourceType.type)) {
54 // generic way of converting an object into a map
55 val dataclassAsMap = jacksonObjectMapper().convertValue(source as MyDTO, object :
56 TypeReference<Map<String, Any>>() {})
57 Values.value(dataclassAsMap)
58 } else null
59 }
60}
61import org.springframework.context.annotation.Bean
62import org.springframework.context.annotation.Configuration
63import org.springframework.data.neo4j.core.convert.Neo4jConversions
64import org.springframework.core.convert.converter.GenericConverter
65import java.util.*
66
67
68@Configuration
69class MyNeo4jConfig {
70 @Bean
71 override fun neo4jConversions(): Neo4jConversions? {
72 val additionalConverters: Set<GenericConverter?> = Collections.singleton(DtoToNeo4jValueConverter())
73 return Neo4jConversions(additionalConverters)
74 }
75}
76
QUESTION
Gremlin: Return new edges created in a query without saving them (equivalent to APOC vRelationship)
Asked 2022-Mar-14 at 14:37I have a graph with two types of nodes: Persons and Houses. In this graph, persons can sell houses (SELLS
relationship), and houses are bought by persons (IS_BOUGHT_BY
relationship). This could be represented as the following diagram:
1(Person_1)-[:SELLS]->(House_1)-[:IS_BOUGHT_BY]->(Person_2)
2
A basic example of this diagram can be created in Neo4j by running:
1(Person_1)-[:SELLS]->(House_1)-[:IS_BOUGHT_BY]->(Person_2)
2CREATE(Person_1: Person {name:'Person 1'})
3CREATE(House_1: House {name:'House 1', deal: 10238})
4CREATE(Person_2: Person {name:'Person 2'})
5
6CREATE
7(Person_1)-[:SELLS]->(House_1),
8(House_1)-[:IS_BOUGHT_BY]->(Person_2)
9
or can be created in Gremlin by executing:
1(Person_1)-[:SELLS]->(House_1)-[:IS_BOUGHT_BY]->(Person_2)
2CREATE(Person_1: Person {name:'Person 1'})
3CREATE(House_1: House {name:'House 1', deal: 10238})
4CREATE(Person_2: Person {name:'Person 2'})
5
6CREATE
7(Person_1)-[:SELLS]->(House_1),
8(House_1)-[:IS_BOUGHT_BY]->(Person_2)
9g.
10 addV('Person').property('name', 'Person 1').as('p1').
11 addV('House').property('name', 'House 1').property('deal', 10238).as('h1').
12 addV('Person').property('name', 'Person 1').as('p2').
13 addE('SELLS').from('p1').to('h1').
14 addE('IS_BOUGHT_BY').from('h1').to('p2')
15
I want to make a query that returns these Person nodes connected with a fake edge called SELLS_HOUSE_TO
without saving this relationship in the database. Also this SELLS_HOUSE_TO
relationship must have as deal property the deal id of the house sold by Person 1 and bought by Person 2. In other words, I want the output of the query to follow the following diagram:
1(Person_1)-[:SELLS]->(House_1)-[:IS_BOUGHT_BY]->(Person_2)
2CREATE(Person_1: Person {name:'Person 1'})
3CREATE(House_1: House {name:'House 1', deal: 10238})
4CREATE(Person_2: Person {name:'Person 2'})
5
6CREATE
7(Person_1)-[:SELLS]->(House_1),
8(House_1)-[:IS_BOUGHT_BY]->(Person_2)
9g.
10 addV('Person').property('name', 'Person 1').as('p1').
11 addV('House').property('name', 'House 1').property('deal', 10238).as('h1').
12 addV('Person').property('name', 'Person 1').as('p2').
13 addE('SELLS').from('p1').to('h1').
14 addE('IS_BOUGHT_BY').from('h1').to('p2')
15(Person_1)-[:SELLS_HOUSE_TO {deal: house_1_deal}]->(Person_2)
16
where id_deal
is the deal property of the House_1
node, which connects Person_1
and Person_2
through the SELLS
and IS_BOUGHT_BY
relationships respectively.
This query can be easily done in Neo4j by using the vRelationship
function provided by the APOC library:
1(Person_1)-[:SELLS]->(House_1)-[:IS_BOUGHT_BY]->(Person_2)
2CREATE(Person_1: Person {name:'Person 1'})
3CREATE(House_1: House {name:'House 1', deal: 10238})
4CREATE(Person_2: Person {name:'Person 2'})
5
6CREATE
7(Person_1)-[:SELLS]->(House_1),
8(House_1)-[:IS_BOUGHT_BY]->(Person_2)
9g.
10 addV('Person').property('name', 'Person 1').as('p1').
11 addV('House').property('name', 'House 1').property('deal', 10238).as('h1').
12 addV('Person').property('name', 'Person 1').as('p2').
13 addE('SELLS').from('p1').to('h1').
14 addE('IS_BOUGHT_BY').from('h1').to('p2')
15(Person_1)-[:SELLS_HOUSE_TO {deal: house_1_deal}]->(Person_2)
16MATCH (p1: Person)-[r1:SELLS]->(h1: House)-[r2:BUYS]->(p2: Person)
17CALL apoc.create.vRelationship(p1, 'SELLS_HOUSE_TO', {deal: h1.deal}, p2) YIELD rel
18RETURN p1, rel, p2
19
It is possible to do something similar in Gremlin without involving storing the edges in the database at some step?
ANSWER
Answered 2022-Mar-14 at 14:37Currently, Gremlin, outside of perhaps using in-line code (closure/lambda), has no way to inject virtual edges into a query result. This might be a good feature request to open as a Jira ticket for Apache Tinkerpop at this location.
As a short term solution, I think the best you can do is to create the edges for the needs of a visualization and perhaps give them a unique property key and value something like "virtual":true
and to delete such edges when no longer needed.
QUESTION
FIlter the list with a condition in Neo4J
Asked 2022-Mar-11 at 14:05Suppose I have a table of this sort
1| Type | Name | Status |
2| -------- | -------------- | -------- |
3| ["Thriller" , "Horror"] | Conjuring | Released |
4| ["Action" , "Thriller"] | Evil Dead | Released |
5| ["Drama" , "Thriller"] | XYZ | Released |
6
I want to retrieve the rows that are not Thriller. In other words I want to do something like Type.filter(item => item != "Thriller")
How can I do this in Neo4J?
Expected Result
1| Type | Name | Status |
2| -------- | -------------- | -------- |
3| ["Thriller" , "Horror"] | Conjuring | Released |
4| ["Action" , "Thriller"] | Evil Dead | Released |
5| ["Drama" , "Thriller"] | XYZ | Released |
6| Type | Name |
7| -------- | -------------- |
8| "Horror" | Conjuring |
9| "Action" | Evil Dead |
10| "Drama" | XYZ |
11
ANSWER
Answered 2022-Mar-11 at 11:06Cypher has a list comprehension syntax:
1| Type | Name | Status |
2| -------- | -------------- | -------- |
3| ["Thriller" , "Horror"] | Conjuring | Released |
4| ["Action" , "Thriller"] | Evil Dead | Released |
5| ["Drama" , "Thriller"] | XYZ | Released |
6| Type | Name |
7| -------- | -------------- |
8| "Horror" | Conjuring |
9| "Action" | Evil Dead |
10| "Drama" | XYZ |
11[x in type WHERE x <> "Thriller" | x]
12
Find more info in docs: https://neo4j.com/docs/cypher-manual/current/syntax/lists/#cypher-list-comprehension
QUESTION
Can't load CSV from Drive to Neo4j
Asked 2022-Mar-09 at 05:08I am using the following cypher code:
1LOAD CSV FROM "https://drive.google.com/file/d/12DiEwM8XatMZBXA6TdekxWl8qrsgVj3l/view?usp=sharing" AS requests RETURN requests
2
and getting the following error:
1LOAD CSV FROM "https://drive.google.com/file/d/12DiEwM8XatMZBXA6TdekxWl8qrsgVj3l/view?usp=sharing" AS requests RETURN requests
2At https://drive.google.com/file/d/12DiEwM8XatMZBXA6TdekxWl8qrsgVj3l/view?usp=sharing @ position 1691 - there's a field starting with a quote and whereas it ends that quote there seems to be characters in that field after that ending quote. That isn't supported. This is what I read: 'docs-fwds":'
3
Please advise how to fix it, I want to be able to load a simple CSV file from Drive to Neo4j.
ANSWER
Answered 2021-Aug-09 at 20:20You need to use the download link instead of the sharing link. This works for me:
1LOAD CSV FROM "https://drive.google.com/file/d/12DiEwM8XatMZBXA6TdekxWl8qrsgVj3l/view?usp=sharing" AS requests RETURN requests
2At https://drive.google.com/file/d/12DiEwM8XatMZBXA6TdekxWl8qrsgVj3l/view?usp=sharing @ position 1691 - there's a field starting with a quote and whereas it ends that quote there seems to be characters in that field after that ending quote. That isn't supported. This is what I read: 'docs-fwds":'
3LOAD CSV WITH HEADERS FROM "https://drive.google.com/u/0/uc?id=12DiEwM8XatMZBXA6TdekxWl8qrsgVj3l&export=download" as row
4RETURN row LIMIT 5
5
I got the download link by clicking on the download icon, which redirects you. You have to be fast to copy the redirect link and it should work. Perhaps there is a method with which you could reconstruct the query manually, so you don't have to be extremely fast to copy the download link, but I am not aware of it.
QUESTION
Is it possible to connect to AuraDB with neomodel?
Asked 2022-Mar-01 at 16:13Is it possible to connect to AuraDB with neomodel
?
AuraDB connection URI is like neo4j+s://xxxx.databases.neo4j.io
.
This is not contained user/password information.
However, connection config of neomodel is bolt and it is contained user/password information.
config.DATABASE_URL = 'bolt://neo4j:password@localhost:7687'
ANSWER
Answered 2022-Mar-01 at 16:13Connecting to neo4j Aura uses neo4j+s protocol so you need to use the provided uri by Aura.
Reference: https://neo4j.com/developer/python/#driver-configuration
In example below; you can set the database url by setting the userid and password along with the uri. It works for me so it should also work for you.
1from neomodel import config
2
3user = 'neo4j'
4psw = 'awesome_password'
5uri = 'awesome.databases.neo4j.io'
6
7config.DATABASE_URL = 'neo4j+s://{}:{}@{}'.format(user, psw, uri)
8print(config.DATABASE_URL)
9
10Result:
11
12 neo4j+s://neo4j:awesome_password@awesome.databases.neo4j.io
13
QUESTION
GraphQL Custom directive enforcing value restrictions
Asked 2022-Jan-13 at 11:52I need to create a custom directive on INPUT_FIELD_DEFINITION to check if the provided value of the enum isn't being changed to the previous "state" (business logic is that states must go UNAPPROVED - > APPROVED -> CANCELLED -> FULFILLED) but can't quite figure out how to map values in constructor of the enum type.
All my code is available at github
I'm using nextJs backend functionality with neo4j database that generates resolvers for whole schema.
1// order Schema
2
3export const order = gql`
4 type Order {
5 id: ID! @id
6 state: OrderState!
7 user: User! @relationship(type: "MADE", direction: IN)
8 createdAt: DateTime! @timestamp(operations: [CREATE])
9 products: [Product!] @relationship(type: "INCLUDE", direction: OUT)
10 }
11
12 enum OrderState {
13 UNAPPROVED
14 APPROVED
15 CANCELLED
16 FULFILLED
17 }
18`;
19
20export const extendOrder = gql`
21 extend input OrderCreateInput {
22 state: OrderState!
23 }
24`;
25
I want to create @checkState
directive that would check if the updating state
is valid
I used as a base example from GraphQL Tools docs but it's with string values. I would much appreciate any help.
ANSWER
Answered 2022-Jan-13 at 11:52Instead of using custom directive I used graphql-middleware
lib to create middleware that is triggered only when updateOrders mutation is being used.
1// order Schema
2
3export const order = gql`
4 type Order {
5 id: ID! @id
6 state: OrderState!
7 user: User! @relationship(type: "MADE", direction: IN)
8 createdAt: DateTime! @timestamp(operations: [CREATE])
9 products: [Product!] @relationship(type: "INCLUDE", direction: OUT)
10 }
11
12 enum OrderState {
13 UNAPPROVED
14 APPROVED
15 CANCELLED
16 FULFILLED
17 }
18`;
19
20export const extendOrder = gql`
21 extend input OrderCreateInput {
22 state: OrderState!
23 }
24`;
25Middleware
26
27import { ValidationError } from "apollo-server-micro";
28import { IMiddleware } from "graphql-middleware";
29import { Order } from "pages/api/graphql";
30
31export const checkStateMiddleware: IMiddleware = {
32 Mutation: {
33 updateOrders: async (resolve, parent, args, ctx, info) => {
34 const { where, update } = args;
35
36 const [existing] = await Order.find({
37 ...where,
38 });
39
40 const states = ["UNAPPROVED", "APPROVED", "CANCELLED", "FULLFIELD"];
41
42 const currentState = states.indexOf(existing.state);
43 const toBeUpdatedState = states.indexOf(update.state);
44
45 if (toBeUpdatedState < currentState) {
46 throw new ValidationError("Can't update value with previous state.");
47 }
48
49 return resolve(parent, args);
50 },
51 },
52};
53
then I apply it in pages/api/graphql.ts
1// order Schema
2
3export const order = gql`
4 type Order {
5 id: ID! @id
6 state: OrderState!
7 user: User! @relationship(type: "MADE", direction: IN)
8 createdAt: DateTime! @timestamp(operations: [CREATE])
9 products: [Product!] @relationship(type: "INCLUDE", direction: OUT)
10 }
11
12 enum OrderState {
13 UNAPPROVED
14 APPROVED
15 CANCELLED
16 FULFILLED
17 }
18`;
19
20export const extendOrder = gql`
21 extend input OrderCreateInput {
22 state: OrderState!
23 }
24`;
25Middleware
26
27import { ValidationError } from "apollo-server-micro";
28import { IMiddleware } from "graphql-middleware";
29import { Order } from "pages/api/graphql";
30
31export const checkStateMiddleware: IMiddleware = {
32 Mutation: {
33 updateOrders: async (resolve, parent, args, ctx, info) => {
34 const { where, update } = args;
35
36 const [existing] = await Order.find({
37 ...where,
38 });
39
40 const states = ["UNAPPROVED", "APPROVED", "CANCELLED", "FULLFIELD"];
41
42 const currentState = states.indexOf(existing.state);
43 const toBeUpdatedState = states.indexOf(update.state);
44
45 if (toBeUpdatedState < currentState) {
46 throw new ValidationError("Can't update value with previous state.");
47 }
48
49 return resolve(parent, args);
50 },
51 },
52};
53//...
54import { applyMiddleware } from "graphql-middleware";
55//...
56const schemaWithMiddleware = applyMiddleware(schema, checkStateMiddleware);
57
58const apolloServer = new ApolloServer({ schema: schemaWithMiddleware });
59//...
60
QUESTION
Is neo4j 3.5 impacted by CVE-2021-44228?
Asked 2021-Dec-15 at 15:28I found that only neo4j > 4.2 is impacted by this vulnerability (here and here )
But in neo4j 3.5.21 pom I see a dependency to log4j (here):
1<dependency>
2 <groupId>log4j</groupId>
3 <artifactId>log4j</artifactId>
4 <version>1.2.17</version>
5</dependency>
6
So is this version really safe for use in production environment right now ?
ANSWER
Answered 2021-Dec-13 at 14:07Is seems that log4j
version 1.2.17
is used in neo4j 3.5.21
and this version is not vulnerable to https://nvd.nist.gov/vuln/detail/CVE-2021-44228 as the vulnerability was introduced with version 2.10.0.
In any way log4j
version 1.2.17
is vulnerable to https://nvd.nist.gov/vuln/detail/CVE-2019-17571 which has a score of 9.8 out of 10. It is a different attack vector maybe harder to exploit, but same as critical and should not be used in production.
You should update your neo4j version in any way.
QUESTION
Neo4j: Get nodes that are at least related with some items of a list
Asked 2021-Dec-12 at 19:13I have a Neo4j database where i have ingredient nodes and recipe nodes. One recipe is connected to many nodes, so, for a simple cheddar sandwich, the recipe node would be connected to bread and cheddar cheese. What i wanted to achieve is to query all the recipes that contain for example at least pepper and salt so if my recipe has pepper, salt and ham it would match. What i have tried following this example is:
1WITH ['pepper', 'salt'] as ingredients
2MATCH (i:Ingredient)-[:INGREDIENT_OF]->(r:Recipe)
3WHERE i.name in ingredients
4WITH r, size(ingredients) as inputCnt, count(DISTINCT i) as cnt
5WHERE cnt = inputCnt
6RETURN r;
7
But it only matches the recipes where the exact ingredients are only pepper and salt. How can i achieve this?
ANSWER
Answered 2021-Dec-12 at 18:58This looks like a very awkward way of doing this.
Most people would use a relational database and SQL.
The database would have a table that stores the relation "ingredient is used in recipe" which connects the ingredient ID to the recipe ID.
Then you write
1WITH ['pepper', 'salt'] as ingredients
2MATCH (i:Ingredient)-[:INGREDIENT_OF]->(r:Recipe)
3WHERE i.name in ingredients
4WITH r, size(ingredients) as inputCnt, count(DISTINCT i) as cnt
5WHERE cnt = inputCnt
6RETURN r;
7SELECT recipe_id FROM used_in WHERE ingredient_id = ingedient1
8 AND ingredient_id = ingedient2;
9
Thats's it! You get a list of all the recipes that use both ingredients and possible others beside
Community Discussions contain sources that include Stack Exchange Network
Tutorials and Learning Resources in Neo4j
Tutorials and Learning Resources are not available at this moment for Neo4j