@@ -35,20 +35,23 @@ include::https://github.com/langchain4j/langchain4j-examples/raw/main/neo4j-exam
35
35
36
36
An example is avalable at: https://github.com/langchain4j/langchain4j-examples/tree/main/neo4j-example
37
37
38
+ ////
39
+ Full include might be a bit too much?
38
40
[source,java]
39
41
----
40
42
include::https://github.com/langchain4j/langchain4j-examples/raw/main/neo4j-example/src/main/java/Neo4jEmbeddingStoreExample.java[]
41
43
----
44
+ ////
45
+
46
+ === Connection Setup
42
47
43
- To create a Neo4jEmbeddingStore, we can write:
44
48
[source,java]
45
49
----
46
50
Neo4jEmbeddingStore embeddingStore = Neo4jEmbeddingStore.builder().<builderParameters>.build();
47
51
48
-
49
-
50
52
// we can use with `withBasicAuth`
51
53
.withBasicAuth(neo4jContainer.getBoltUrl(), USERNAME, ADMIN_PASSWORD)
54
+
52
55
// as alternative to driver:
53
56
Driver driver = GraphDatabase.driver(neo4jContainer.getBoltUrl(), AuthTokens.basic(USERNAME, ADMIN_PASSWORD));
54
57
----
@@ -72,16 +75,17 @@ Here is the complete builder list:
72
75
| textProperty | "text" | the text property name
73
76
| indexName | "vector" | the vector index name
74
77
| databaseName | "neo4j" | the database name
75
- | retrievalQuery | "RETURN properties(node) AS metadata, node.` idProperty` AS ` idProperty` , node.` textProperty` AS ` textProperty` , node.` embeddingProperty` AS ` embeddingProperty` , score" | the retrieval query
78
+ | retrievalQuery | "RETURN properties(node) AS metadata, node.idProperty AS idProperty, node.textProperty AS textProperty, node.embeddingProperty AS embeddingProperty, score" | the retrieval query
76
79
|===
77
80
78
- === Usage Examples
81
+ == Usage Examples
79
82
80
83
LangChain4j provides the following classes for Neo4j integration:
84
+
81
85
- `Neo4jEmbeddingStore`: Implements the EmbeddingStore interface, enabling storing and querying vector embeddings in a Neo4j database.
82
86
- `Neo4jText2CypherRetriever`: Implements the ContentRetriever interface for generating and executing Cypher queries from user questions, improving content retrieval from Neo4j databases.
83
87
84
- ==== Neo4jEmbeddingStore
88
+ === Neo4jEmbeddingStore
85
89
86
90
We can define an `Neo4jEmbeddingStore` with the required Java Driver instance and dimension and an optional label name in this way:
87
91
@@ -96,33 +100,17 @@ Neo4jEmbeddingStore embeddingStore = Neo4jEmbeddingStore.builder()
96
100
.build();
97
101
----
98
102
99
- We can use `withBasicAuth` as an alternative to `driver` creation:
100
- [source,java]
101
- ----
102
- Neo4jEmbeddingStore embeddingStore = Neo4jEmbeddingStore.builder()
103
- .withBasicAuth('<boltURL>', '<username>', '<password>')
104
- .<otherBuilderParameters>
105
- .build();
106
-
107
- /* instead of
108
- Driver driver = GraphDatabase.driver('<boltURL>', AuthTokens.basic('<username>', '<password>'));
109
- Neo4jEmbeddingStore embeddingStore = Neo4jEmbeddingStore.builder()
110
- .withDriver(driver)
111
- .<otherBuilderParameters>
112
- .build()
113
- */
114
-
115
- ----
116
-
117
103
To add embeddings, execute:
104
+
118
105
[source,java]
119
106
----
120
107
Embedding embedding = embeddingModel.embed("embedText").content();
121
108
String id = embeddingStore.add(embedding);
122
109
// output: id of the embedding
123
110
----
124
111
125
- To add embeddings with id:
112
+ To add embeddings with an id:
113
+
126
114
[source,java]
127
115
----
128
116
String id = randomUUID();
@@ -131,7 +119,18 @@ embeddingStore.add(id, embedding);
131
119
// output: id of the embedding
132
120
----
133
121
134
- To add embeddings with segment:
122
+ Add multiple embeddings:
123
+
124
+ [source,java]
125
+ ----
126
+ Embedding firstEmbedding = embeddingModel.embed("firstEmbedText").content();
127
+ Embedding secondEmbedding = embeddingModel.embed("secondEmbedText").content();
128
+ List<String> ids = embeddingStore.addAll(asList(firstEmbedding, secondEmbedding));
129
+ // output: list of the embedding ids
130
+ ----
131
+
132
+ To add embeddings with a `TextSegment`:
133
+
135
134
[source,java]
136
135
----
137
136
TextSegment segment = TextSegment.from(randomUUID());
@@ -140,7 +139,8 @@ String id = embeddingStore.add(embedding, segment);
140
139
// output: id of the embedding
141
140
----
142
141
143
- To add embeddings with segment and metadata:
142
+ To add embeddings with `TextSegment` and metadata:
143
+
144
144
[source,java]
145
145
----
146
146
TextSegment segment = TextSegment.from(randomUUID(), Metadata.from(METADATA_KEY, "test-value"));
@@ -149,20 +149,24 @@ String id = embeddingStore.add(embedding, segment);
149
149
// output: id of the embedding
150
150
----
151
151
152
- Search embeddings:
152
+ Add multiple embeddings with segments
153
+
153
154
[source,java]
154
155
----
155
- Embedding embedding = embeddingModel.embed("embedText").content();
156
- String id = embeddingStore.add(embedding);
157
- final EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
158
- .queryEmbedding(embedding)
159
- .maxResults(10)
160
- .build();
161
- final List<EmbeddingMatch<TextSegment>> relevant = embeddingStore.search(request).matches();
162
- // output: list of embeddings
156
+ TextSegment firstSegment = TextSegment.from("firstText");
157
+ Embedding firstEmbedding = embeddingModel.embed(firstSegment.text()).content();
158
+
159
+ TextSegment secondSegment = TextSegment.from("secondText");
160
+ Embedding secondEmbedding = embeddingModel.embed(secondSegment.text()).content();
161
+
162
+ List<String> ids = embeddingStore.addAll(
163
+ asList(firstEmbedding, secondEmbedding),
164
+ asList(firstSegment, secondSegment)
165
+ );
166
+ // output: list of the embedding ids
163
167
----
164
168
165
- To search embeddings with `minScore` :
169
+ Search embeddings:
166
170
167
171
[source,java]
168
172
----
@@ -171,13 +175,15 @@ String id = embeddingStore.add(embedding);
171
175
final EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
172
176
.queryEmbedding(embedding)
173
177
.maxResults(10)
174
- .minScore(0.15)
178
+ .minScore(0.15) // Optional `minScore`
175
179
.build();
180
+
176
181
final List<EmbeddingMatch<TextSegment>> relevant = embeddingStore.search(request).matches();
177
182
// output: list of embeddings
178
183
----
179
184
180
185
To search embeddings with segment with custom metadata prefix:
186
+
181
187
[source,java]
182
188
----
183
189
String metadataPrefix = "metadata.";
@@ -192,6 +198,7 @@ Neo4jEmbeddingStore embeddingStore = Neo4jEmbeddingStore.builder()
192
198
.build();
193
199
194
200
String metadataCompleteKey = metadataPrefix + METADATA_KEY;
201
+
195
202
TextSegment segment = TextSegment.from(randomUUID(), Metadata.from(METADATA_KEY, "test-value"));
196
203
Embedding embedding = embeddingModel.embed(segment.text()).content();
197
204
@@ -206,7 +213,8 @@ final List<EmbeddingMatch<TextSegment>> relevant = embeddingStore.search(request
206
213
// output: list of embeddings
207
214
----
208
215
209
- Search embeddings with segment with metadata and custom id prop:
216
+ Search embeddings with segment with metadata-prefix and custom id property name:
217
+
210
218
[source,java]
211
219
----
212
220
String metadataPrefix = "metadata.";
@@ -236,44 +244,10 @@ final List<EmbeddingMatch<TextSegment>> relevant = embeddingStore.search(request
236
244
// output: list of embeddings
237
245
----
238
246
239
- Add multiple embeddings
240
- [source,java]
241
- ----
242
- Embedding firstEmbedding = embeddingModel.embed("firstEmbedText").content();
243
- Embedding secondEmbedding = embeddingModel.embed("secondEmbedText").content();
244
- List<String> ids = embeddingStore.addAll(asList(firstEmbedding, secondEmbedding));
245
- // output: list of the embedding ids
246
-
247
- final EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
248
- .queryEmbedding(firstEmbedding)
249
- .maxResults(10)
250
- .build();
251
- final List<EmbeddingMatch<TextSegment>> relevant = embeddingStore.search(request).matches();
252
- // output: list of embeddings
253
- ----
254
-
255
- Add multiple embeddings with segments
256
- [source,java]
257
- ----
258
- TextSegment firstSegment = TextSegment.from("firstText");
259
- Embedding firstEmbedding = embeddingModel.embed(firstSegment.text()).content();
260
- TextSegment secondSegment = TextSegment.from("secondText");
261
- Embedding secondEmbedding = embeddingModel.embed(secondSegment.text()).content();
247
+ === Neo4jText2CypherRetriever
262
248
263
- List<String> ids = embeddingStore.addAll(
264
- asList(firstEmbedding, secondEmbedding),
265
- asList(firstSegment, secondSegment)
266
- ); // output: list of the embedding ids
267
-
268
- final EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
269
- .queryEmbedding(firstEmbedding)
270
- .maxResults(10)
271
- .build();
272
- final List<EmbeddingMatch<TextSegment>> relevant = embeddingStore.search(request).matches();
273
- // output: list of embeddings
274
- ----
249
+ // todo more explanation
275
250
276
- ==== Neo4jText2CypherRetriever
277
251
[source,java]
278
252
----
279
253
// create dataset
0 commit comments