Skip to content

Commit 10ca6f7

Browse files
committed
Merge branch '5.x' into 6.x
2 parents 5a8aaf3 + f684297 commit 10ca6f7

30 files changed

+781
-400
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
.scala_dependencies
2424
.settings
2525
.shell_history
26+
.vscode/
2627
Thumbs.db
2728
\#*
2829
bin/teamcity/

modules/ROOT/content-nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
** xref:security/configuration.adoc[]
1111
** xref:security/authentication.adoc[]
1212
** xref:security/authorization.adoc[]
13+
** xref:security/subscriptions-authorization.adoc[]
1314
** xref:security/impersonation-and-user-switching.adoc[]
1415
** xref:security/operations.adoc[]
1516
* xref:types/index.adoc[]

modules/ROOT/pages/directives/autogeneration.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ This enables autogeneration of IDs for the field.
1515
The format of each generated ID is a UUID generated by the link:https://neo4j.com/docs/cypher-manual/current/functions/scalar/#functions-randomuuid[`randomUUID()` function].
1616
The field will not be present in input types for mutations.
1717

18-
It is recommended to use xref::/directives/indexes-and-constraints.adoc#type-definitions-constraints-unique[`@unique`] in conjunction with this to add a unique node property constraint.
18+
It is recommended to use xref::/directives/indexes-and-constraints.adoc#_unique_node_property_constraints[`@unique`] in conjunction with this to add a unique node property constraint.
1919

2020
=== Definition
2121

modules/ROOT/pages/directives/custom-logic.adoc

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,17 @@ Global variables are available for use within the Cypher statement, and can be a
2020
a|
2121
[source, graphql, indent=0]
2222
----
23-
{
24-
Movie {
25-
title
26-
actors: ACTED_IN @this {
27-
role
28-
actor {
29-
name
30-
}
31-
}
32-
directors: DIRECTED @this {
33-
director {
34-
name
35-
}
36-
}
37-
}
23+
type Movie {
24+
title: String
25+
similarMovies(limit: Int = 10): [Movie]
26+
@cypher(
27+
statement: """
28+
MATCH (this)<-[:ACTED_IN]-(:Actor)-[:ACTED_IN]->(rec:Movie)
29+
WITH rec, COUNT(*) AS score ORDER BY score DESC
30+
RETURN rec LIMIT $limit
31+
""",
32+
columnName: "rec"
33+
)
3834
}
3935
----
4036

@@ -300,7 +296,6 @@ type Movie {
300296
}
301297
----
302298

303-
[[type-definitions-default-values-limit]]
304299
== `@limit`
305300

306301
Available on nodes, this directive injects values into a query such as the `limit`.

modules/ROOT/pages/directives/database-mapping.adoc

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,21 @@ The following query yields a different Cypher query depending on the user JWT:
183183
users {
184184
name
185185
}
186-
}ref::/directives/database-mapping.adoc#_declarerelationship[
186+
}
187+
----
188+
189+
Assuming there is a user with the value `"username": "arthur"` in JWT, the Cypher query looks like:
190+
191+
[source, cypher, indent=0]
192+
----
193+
MATCH (this:arthur)
194+
RETURN this { .name } as this
195+
----
196+
197+
Similarly, context values can be passed directly:
198+
199+
[source, graphql, indent=0]
200+
----
187201
type User @node(label: ["$context.appId"]) {
188202
name: String!
189203
}

modules/ROOT/pages/directives/index.adoc

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ The Neo4j GraphQL Library provides the following directives to be used whilst de
1414
| xref::/directives/database-mapping.adoc#_relationship[`@relationship`]
1515
| Configures xref::/types/relationships.adoc[relationships] between object types.
1616

17-
| xref::/directives/database-mapping.adoc#_relationship_properties[`@relationshipProperties`]
17+
| xref::/directives/database-mapping.adoc#_relationshipproperties[`@relationshipProperties`]
1818
a| Required to differentiate interfaces that are used for relationship properties, and otherwise.
1919

2020
| xref::/directives/database-mapping.adoc#type-definitions-node[`@node`]
@@ -40,14 +40,14 @@ a| Required to differentiate interfaces that are used for relationship propertie
4040
| xref::/security/authorization.adoc[`@authorization`]
4141
| Specifies authorization rules for queries and mutations on the type.
4242

43-
| xref::/security/configuration.adoc#authentication-and-authorization-jwt[`@jwt`]
43+
| xref::/security/configuration.adoc#_the_jwt_directive[`@jwt`]
4444
| Configures the JWT authentication and authorization filters to include additional JWT claims.
4545

46-
| xref::/security/configuration.adoc#_nested_claims[`@jwtClaim`]
46+
| xref::/security/configuration.adoc#_the_jwtclaim_directive[`@jwtClaim`]
4747
| Used in combination with `@jwt`.
4848
Configures the JWT authentication and authorization filters to include an additional JWT claim which is either nested or using special characters not supported by GraphQL.
4949

50-
| `@subscriptionsAuthorization`
50+
| xref::/security/subscriptions-authorization.adoc[`@subscriptionsAuthorization`]
5151
| Specifies authorization rules for subscriptions on the type.
5252

5353
|===
@@ -105,12 +105,15 @@ Particularly useful for types that are not correctly pluralized or are non-Engli
105105
|===
106106
| Directive | Description
107107

108-
| xref::/directives/indexes-and-constraints.adoc#type-definitions-indexes-fulltext[`@fulltext`]
108+
| xref::/directives/indexes-and-constraints.adoc#_fulltext_indexes[`@fulltext`]
109109
| Indicates that there should be a fulltext index inserted into the database for the specified Node and its properties.
110110

111-
| xref::/directives/indexes-and-constraints.adoc#type-definitions-constraints-unique[`@unique`]
111+
| xref::/directives/indexes-and-constraints.adoc#_unique_node_property_constraints[`@unique`]
112112
| Indicates that there should be a uniqueness constraint in the database for the fields that it is applied to.
113113

114+
| xref::/directives/indexes-and-constraints.adoc#_vector_index_search[`@vector`]
115+
| Perform a vector index search on your database either based by passing in a vector index or a search phrase. label:beta[]
116+
114117
|===
115118

116119
== Custom logic

modules/ROOT/pages/directives/indexes-and-constraints.adoc

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,191 @@ const schema = await neoSchema.getSchema();
247247
248248
await neoSchema.assertIndexesAndConstraints({ options: { create: true }});
249249
----
250+
251+
252+
:description: Directives related to generative AI in the Neo4j GraphQL Library.
253+
254+
[role=label--beta]
255+
== Vector index search
256+
257+
With the `@vector` GraphQL directive you can query your database to perform a vector index search.
258+
Queries are performed by passing in either a vector index or a query phrase.
259+
260+
A query by vector index finds nodes with a vector embedding similar to that index.
261+
That is, the query performs a nearest neighbor search.
262+
263+
In contrast, a query by phrase (a string of text) forwards the phrase to the link:https://neo4j.com/docs/cypher-manual/current/genai-integrations/[Neo4j GenAI plugin] and the plugin generates a vector embedding for it.
264+
This embedding is then compared to the node vector embeddings in the database.
265+
266+
[NOTE]
267+
.Prerequisites
268+
====
269+
* The database must be Neo4j version 5.15 or higher.
270+
* The node vector embeddings already exist in the database. See link:https://neo4j.com/docs/cypher-manual/current/indexes/semantic-indexes/vector-indexes/[Vector indexes] to learn more about vector indexes in Cypher and Neo4j.
271+
* The embeddings must have been created using the same method, that is, the same provider and model. See link:https://neo4j.com/docs/genai/tutorials/embeddings-vector-indexes/[Embeddings & Vector Indexes Tutorial] to learn about vector embeddings in Cypher and Neo4j.
272+
* Queries by vector index cannot be performed across multiple labels.
273+
* Queries by phrase require credentials for the Neo4j GenAI plugin.
274+
====
275+
276+
[NOTE]
277+
====
278+
Vector index searches are _read-only_ in the sense that the data which the queries operate on are retrieved from the database but not altered or written back to the database.
279+
====
280+
281+
282+
=== Definition
283+
284+
[source, graphql]
285+
----
286+
"""Informs @neo4j/graphql that there should be a vector index in the database, allows users to search by the index in the generated schema."""
287+
directive @vector(indexes: [VectorIndexInput]!) on OBJECT
288+
----
289+
290+
`VectorIndexInput` is defined as follows:
291+
292+
[source, graphql]
293+
----
294+
input VectorIndexInput {
295+
"""(Required) The name of the vector index."""
296+
indexName: String!
297+
"""(Required) The name of the embedding property on the node."""
298+
embeddingProperty: String!
299+
"""(Required) The name of the query."""
300+
queryName: String
301+
"""(Optional) The name of the provider."""
302+
provider: String
303+
}
304+
----
305+
306+
If the optional field `provider` is set, the type is used for a query by phrase, otherwise for a query by vector.
307+
Allowed values for the `provider` field are defined by the available link:https://neo4j.com/docs/cypher-manual/current/genai-integrations/#ai-providers[GenAI providers].
308+
309+
310+
=== Usage
311+
312+
==== Query by vector index
313+
314+
Perform a nearest neighbor search by passing a vector to find nodes with a vector embedding similar to that vector.
315+
316+
.Type definition
317+
[source, graphql]
318+
----
319+
type Product @vector(indexes: [{
320+
indexName: "productDescriptionIndex",
321+
embeddingProperty: "descriptionVector",
322+
queryName: "searchByDescription"
323+
}]) {
324+
id: ID!
325+
name: String!
326+
description: String!
327+
}
328+
----
329+
330+
This defines the query to be performed on all `Product` nodes which have a vector index named `productDescriptionIndex` for the property `descriptionVector`, implying that a vector embedding has been created for the `description` property of each node.
331+
332+
.Example query
333+
[source, graphql]
334+
----
335+
query FindSimilarProducts($vector: [Float]!) {
336+
searchByDescription(vector: $vector) {
337+
productsConnection {
338+
edges {
339+
cursor
340+
score
341+
node {
342+
id
343+
name
344+
description
345+
}
346+
}
347+
}
348+
}
349+
}
350+
----
351+
352+
The input `$vector` is a list of `FLOAT` values and should look similar to this:
353+
354+
.An example vector
355+
[source, graphql]
356+
----
357+
{
358+
"vector": [
359+
0.123456,
360+
...,
361+
0.654321,
362+
]
363+
}
364+
----
365+
366+
The query returns all `Product` nodes with a vector embedding on their `descriptionVector` property which is similar to the query argument `$vector`.
367+
368+
==== Query by phrase
369+
370+
Perform a query which utilizes the link:https://neo4j.com/docs/cypher-manual/current/genai-integrations/[Neo4j GenAI plugin] to create a vector embedding for a search phrase and then compare it to existing vector embeddings on nodes in the database.
371+
372+
[NOTE]
373+
====
374+
Requires credentials for the plugin.
375+
====
376+
377+
Ensure your provider credentials are set in the call to Neo4jGraphQL, for example:
378+
379+
.Feature configuration
380+
[source, graphql]
381+
----
382+
const neoSchema = new Neo4jGraphQL({
383+
typeDefs,
384+
driver,
385+
features: {
386+
vector: {
387+
OpenAI: {
388+
token: "my-open-ai-token",
389+
model: "text-embedding-3-small",
390+
},
391+
},
392+
},
393+
});
394+
----
395+
396+
`OpenAI` is one of the GenAI providers for generating vector embeddings.
397+
See link:https://neo4j.com/docs/cypher-manual/current/genai-integrations/#ai-providers[GenAI providers] for the full list of providers and their respective identifiers.
398+
399+
.Type definition
400+
[source, graphql]
401+
----
402+
type Product @vector(indexes: [{
403+
indexName: "productDescriptionIndex",
404+
embeddingProperty: "descriptionVector",
405+
provider: OPEN_AI, # Assuming this is configured in the server
406+
queryName: "searchByPhrase"
407+
}]) {
408+
id: ID!
409+
name: String!
410+
description: String!
411+
}
412+
----
413+
414+
This defines the query to be performed on all `Product` nodes which have a vector index named `productDescriptionIndex` for the property `descriptionVector`, implying that a vector embedding has been created for the `description` property of each node.
415+
416+
.Example query
417+
[source, graphql]
418+
----
419+
query SearchProductsByPhrase($phrase: String!) {
420+
searchByPhrase(phrase: $phrase) {
421+
productsConnection {
422+
edges {
423+
cursor
424+
score
425+
node {
426+
id
427+
name
428+
description
429+
}
430+
}
431+
}
432+
}
433+
}
434+
----
435+
436+
First, the query passes the query phrase argument `$phrase` to the GenAI plugin and lets it generate a vector embedding for the phrase.
437+
Then it returns all `Product` nodes with a vector embedding on their `descriptionVector` property which are similar to the vector embedding generated by the plugin.

modules/ROOT/pages/directives/schema-configuration/type-configuration.adoc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,11 @@ This directive is used to limit subscription operations in the library.
115115
[source, graphql, indent=0]
116116
----
117117
enum SubscriptionFields {
118-
CREATE
119-
UPDATE
120-
DELETE
121-
CREATE_RELATIONSHIP
122-
DELETE_RELATIONSHIP
118+
CREATED
119+
UPDATED
120+
DELETED
121+
RELATIONSHIP_CREATED
122+
RELATIONSHIP_DELETED
123123
}
124124
125125
directive @subscription(events: [SubscriptionFields!]! = [CREATED, UPDATED, DELETED, RELATIONSHIP_CREATED, RELATIONSHIP_DELETED]) on OBJECT | SCHEMA
@@ -210,4 +210,4 @@ This way, instead of the wrongly generated `teches`, the type is properly writte
210210
----
211211

212212
The same is applied to other operations such as `createTechs`.
213-
However, keep in mind that database labels are not changed with this directive.
213+
However, keep in mind that database labels are not changed with this directive.

modules/ROOT/pages/driver-configuration.adoc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,7 @@ await ogm.checkNeo4jCompat();
216216

217217
== Specifying the Neo4j database
218218

219-
There are two ways to specify which database within a DBMS should be used.
220-
221-
=== Context
219+
Specify the database to be used within your DBMS via the `database` field under `sessionConfig` in the `context` that all resolvers share.
222220

223221
[source, javascript, indent=0]
224222
----

modules/ROOT/pages/getting-started/index.adoc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
This tutorial walks you through creating a new project with the Neo4j GraphQL Library.
77

8-
If you are not familiar with Neo4j and GraphQL, you can alternatively take the course https://graphacademy.neo4j.com/courses/graphql-basics/?ref=docs[Introduction to Neo4j & GraphQL] in GraphAcademy to learn the fundamentals, how to use the xref:getting-started/toolbox.adoc[Neo4j GraphQL Toolbox] and the Neo4j GraphQL Library to create GraphQL APIs backed by a Neo4j graph database.
9-
108
This tutorial shows you how to:
119

1210
- Install the Neo4j GraphQL Library and its dependencies.
@@ -294,3 +292,6 @@ By now, you should have a GraphQL API connected to a Neo4j database, to which yo
294292

295293
To learn more, keep reading the documentation about xref:queries-aggregations/index.adoc[Queries and aggregations] or alternatively learn how to use the xref:getting-started/toolbox.adoc[Neo4j GraphQL Toolbox].
296294
For more advanced database settings, refer to the xref:driver-configuration.adoc[Driver configuration] page.
295+
296+
// Edit at: https://github.com/neo4j-graphacademy/courses/blob/main/asciidoc/courses/graphql-basics/promo.adoc
297+
include::https://raw.githubusercontent.com/neo4j-graphacademy/courses/main/asciidoc/courses/graphql-basics/promo.adoc[]

0 commit comments

Comments
 (0)