Skip to content

Commit d79f288

Browse files
committed
update docstrings and reorganize
1 parent f4ceca5 commit d79f288

File tree

4 files changed

+194
-32
lines changed

4 files changed

+194
-32
lines changed

src/integration/java/io/pinecone/clients/ConnectionsMapTest.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.pinecone.clients;
22

3+
import io.pinecone.configs.PineconeConfig;
34
import io.pinecone.configs.PineconeConnection;
45
import io.pinecone.exceptions.PineconeNotFoundException;
56
import io.pinecone.helpers.RandomStringBuilder;
@@ -57,6 +58,10 @@ public void testMultipleIndexesWithMultipleClients() throws InterruptedException
5758
// Get index1's host
5859
String host1 = indexModel1.getHost();
5960

61+
// Create config1 for getting index connection and set the host
62+
PineconeConfig config1 = new PineconeConfig(System.getenv("PINECONE_API_KEY"));
63+
config1.setHost(host1);
64+
6065
// Create index-2
6166
pinecone1.createServerlessIndex(indexName2,
6267
null,
@@ -72,6 +77,11 @@ public void testMultipleIndexesWithMultipleClients() throws InterruptedException
7277
// Get index2's host
7378
String host2 = indexModel2.getHost();
7479

80+
// Create config2 for getting index connection and set the host
81+
PineconeConfig config2 = new PineconeConfig(System.getenv("PINECONE_API_KEY"));
82+
config1.setHost(host2);
83+
84+
7585
// Establish grpc connection for index-1
7686
Index index1_1 = pinecone1.getIndexConnection(indexName1);
7787
// Get connections map
@@ -94,7 +104,7 @@ public void testMultipleIndexesWithMultipleClients() throws InterruptedException
94104
assertEquals(host2, connectionsMap1_2.get(indexName2).toString());
95105

96106
// Establishing connections with index1 and index2 using another pinecone client
97-
pinecone2.getConnection(indexName1);
107+
pinecone2.getConnection(indexName1, config1);
98108
ConcurrentHashMap<String, PineconeConnection> connectionsMap2_1 = pinecone1.getConnectionsMap();
99109
// Verify the new connections map is pointing to the same reference
100110
assert connectionsMap2_1 == connectionsMap1_2;
@@ -103,7 +113,7 @@ public void testMultipleIndexesWithMultipleClients() throws InterruptedException
103113
// Verify the connection value for index1 is host1
104114
assertEquals(host1, connectionsMap2_1.get(indexName1).toString());
105115

106-
pinecone2.getConnection(indexName2);
116+
pinecone2.getConnection(indexName2, config2);
107117
ConcurrentHashMap<String, PineconeConnection> connectionsMap2_2 = pinecone1.getConnectionsMap();
108118
// Verify the new connections map is pointing to the same reference
109119
assert connectionsMap2_1 == connectionsMap2_2;
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package io.pinecone.integration.dataPlane;
2+
3+
import io.pinecone.clients.Index;
4+
import io.pinecone.clients.Pinecone;
5+
import io.pinecone.helpers.RandomStringBuilder;
6+
import org.junit.jupiter.api.Assertions;
7+
import org.junit.jupiter.api.Test;
8+
import org.openapitools.db_control.client.model.CreateIndexForModelRequest;
9+
import org.openapitools.db_control.client.model.CreateIndexForModelRequestEmbed;
10+
import org.openapitools.db_control.client.model.DeletionProtection;
11+
import org.openapitools.db_data.client.ApiException;
12+
import org.openapitools.db_data.client.model.SearchRecordsRequestQuery;
13+
import org.openapitools.db_data.client.model.SearchRecordsResponse;
14+
import org.openapitools.db_data.client.model.UpsertRecord;
15+
16+
import java.util.ArrayList;
17+
import java.util.HashMap;
18+
import java.util.List;
19+
20+
public class UpsertAndSearchRecordsTest {
21+
@Test
22+
public void upsertAndSearchRecordsTest() throws ApiException, org.openapitools.db_control.client.ApiException, InterruptedException {
23+
Pinecone pinecone = new Pinecone.Builder(System.getenv("PINECONE_API_KEY")).build();
24+
String indexName = RandomStringBuilder.build("inf", 8);
25+
HashMap<String, String> fieldMap = new HashMap<>();
26+
fieldMap.put("text", "chunk_text");
27+
CreateIndexForModelRequestEmbed embed = new CreateIndexForModelRequestEmbed()
28+
.model("multilingual-e5-large")
29+
.fieldMap(fieldMap);
30+
pinecone.createIndexForModel(indexName, CreateIndexForModelRequest.CloudEnum.AWS, "us-west-2", embed, DeletionProtection.DISABLED, new HashMap<>());
31+
32+
// Wait for index to be created
33+
Thread.sleep(10000);
34+
35+
Index index = pinecone.getIndexConnection(indexName);
36+
UpsertRecord record1 = new UpsertRecord();
37+
record1.id("rec1");
38+
record1.putAdditionalProperty("category", "digestive system");
39+
record1.putAdditionalProperty("chunk_text", "Apples are a great source of dietary fiber, which supports digestion and helps maintain a healthy gut.");
40+
ArrayList<UpsertRecord> records = new ArrayList<>();
41+
42+
UpsertRecord record2 = new UpsertRecord();
43+
record2.id("rec2");
44+
record2.putAdditionalProperty("category", "cultivation");
45+
record2.putAdditionalProperty("chunk_text", "Apples originated in Central Asia and have been cultivated for thousands of years, with over 7,500 varieties available today.");
46+
47+
UpsertRecord record3 = new UpsertRecord();
48+
record3.id("rec3");
49+
record3.putAdditionalProperty("category", "immune system");
50+
record3.putAdditionalProperty("chunk_text", "Rich in vitamin C and other antioxidants, apples contribute to immune health and may reduce the risk of chronic diseases.");
51+
52+
UpsertRecord record4 = new UpsertRecord();
53+
record4.id("rec4");
54+
record4.putAdditionalProperty("category", "endocrine system");
55+
record4.putAdditionalProperty("chunk_text", "The high fiber content in apples can also help regulate blood sugar levels, making them a favorable snack for people with diabetes.");
56+
57+
records.add(record1);
58+
records.add(record2);
59+
records.add(record3);
60+
records.add(record4);
61+
62+
index.upsertRecords("example-namespace", records);
63+
String namespace = "example-namespace";
64+
HashMap<String, String> inputsMap = new HashMap<>();
65+
inputsMap.put("text", "Disease prevention");
66+
SearchRecordsRequestQuery query = new SearchRecordsRequestQuery()
67+
.topK(4)
68+
.inputs(inputsMap);
69+
70+
List<String> fields = new ArrayList<>();
71+
fields.add("category");
72+
fields.add("chunk_text");
73+
74+
// Wait for vectors to be upserted
75+
Thread.sleep(5000);
76+
77+
SearchRecordsResponse recordsResponse = index.searchRecords(namespace, query, fields, null);
78+
Assertions.assertEquals(records.size(), recordsResponse.getResult().getHits().size());
79+
Assertions.assertEquals(record3.getId(), recordsResponse.getResult().getHits().get(0).getId());
80+
81+
pinecone.deleteIndex(indexName);
82+
}
83+
}

src/main/java/io/pinecone/clients/Index.java

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ public class Index implements IndexInterface<UpsertResponse,
6666
* Index index = client.getIndexConnection("my-index");
6767
* }</pre>
6868
*
69-
* @param config The {@link PineconeConfig} configuration of the index.
69+
* @param config The {@link PineconeConfig} configuration of the index.
7070
* @param connection The {@link PineconeConnection} configuration to be used for this index.
71-
* @param indexName The name of the index to interact with. The index host will be automatically resolved.
71+
* @param indexName The name of the index to interact with. The index host will be automatically resolved.
7272
* @throws PineconeValidationException if the connection object is null.
7373
*/
7474
public Index(PineconeConfig config, PineconeConnection connection, String indexName) {
@@ -813,7 +813,7 @@ public DescribeIndexStatsResponse describeIndexStats(Struct filter) {
813813
/**
814814
* {@inheritDoc}
815815
* <p> Example:
816-
* <pre>{@code
816+
* <pre>{@code
817817
* import io.pinecone.proto.ListResponse;
818818
*
819819
* ...
@@ -832,7 +832,7 @@ public ListResponse list() {
832832
/**
833833
* {@inheritDoc}
834834
* <p>Example:
835-
* <pre>{@code
835+
* <pre>{@code
836836
* import io.pinecone.proto.ListResponse;
837837
*
838838
* ...
@@ -850,7 +850,7 @@ public ListResponse list(String namespace) {
850850
/**
851851
* {@inheritDoc}
852852
* <p>Example:
853-
* <pre>{@code
853+
* <pre>{@code
854854
* import io.pinecone.proto.ListResponse;
855855
*
856856
* ...
@@ -868,7 +868,7 @@ public ListResponse list(String namespace, int limit, String paginationToken) {
868868
/**
869869
* {@inheritDoc}
870870
* <p>Example:
871-
* <pre>{@code
871+
* <pre>{@code
872872
* import io.pinecone.proto.ListResponse;
873873
*
874874
* ...
@@ -886,7 +886,7 @@ public ListResponse list(String namespace, int limit) {
886886
/**
887887
* {@inheritDoc}
888888
* <p>Example:
889-
* <pre>{@code
889+
* <pre>{@code
890890
* import io.pinecone.proto.ListResponse;
891891
*
892892
* ...
@@ -905,7 +905,7 @@ public ListResponse list(String namespace, String prefix) {
905905
/**
906906
* {@inheritDoc}
907907
* <p> Example:
908-
* <pre>{@code
908+
* <pre>{@code
909909
* import io.pinecone.proto.ListResponse;
910910
*
911911
* ...
@@ -925,7 +925,7 @@ public ListResponse list(String namespace, String prefix, int limit) {
925925
/**
926926
* {@inheritDoc}
927927
* <p>Example:
928-
* <pre>{@code
928+
* <pre>{@code
929929
* import io.pinecone.proto.ListResponse;
930930
*
931931
* ...
@@ -950,22 +950,23 @@ public ListResponse list(String namespace, String prefix, String paginationToken
950950
* through a list of vector IDs. It then makes a synchronous RPC call to fetch the list of vector IDs.
951951
*
952952
* <p>Example:
953-
* <pre>{@code
953+
* <pre>{@code
954954
* import io.pinecone.proto.ListResponse;
955955
*
956956
* ...
957957
*
958958
* ListResponse listResponse = index.list("example-namespace", "st-", "some-pagToken", 10);
959959
* }</pre>
960-
* @param namespace The namespace that holds the vector IDs you want to retrieve. If namespace is not specified,
961-
* the default namespace is used.
962-
* @param prefix The prefix with which vector IDs must start to be included in the response.
960+
*
961+
* @param namespace The namespace that holds the vector IDs you want to retrieve. If namespace is not specified,
962+
* the default namespace is used.
963+
* @param prefix The prefix with which vector IDs must start to be included in the response.
963964
* @param paginationToken The token to paginate through the list of vector IDs.
964-
* @param limit The maximum number of vector IDs you want to retrieve.
965+
* @param limit The maximum number of vector IDs you want to retrieve.
965966
* @return {@link ListResponse} containing the list of vector IDs fetched from the specified namespace.
966-
* The response includes vector IDs up to {@code 100} items.
967+
* The response includes vector IDs up to {@code 100} items.
967968
* @throws RuntimeException if there are issues processing the request or communicating with the server.
968-
* This includes network issues, server errors, or serialization issues with the request or response.
969+
* This includes network issues, server errors, or serialization issues with the request or response.
969970
*/
970971
public ListResponse list(String namespace, String prefix, String paginationToken, int limit) {
971972
validateListEndpointParameters(namespace, prefix, paginationToken, limit, true, true, true, true);
@@ -974,17 +975,81 @@ public ListResponse list(String namespace, String prefix, String paginationToken
974975
return blockingStub.list(listRequest);
975976
}
976977

978+
/**
979+
* <p>Upserts records into a specified namespace within a Pinecone index. This operation
980+
* will insert new records or update existing ones based on the provided data.</p>
981+
*
982+
* <p>The method sends a list of {@link UpsertRecord} objects to the specified namespace
983+
* in the Pinecone index, either inserting new records or updating existing records
984+
* depending on whether the record IDs already exist.</p>
985+
*
986+
* <p>Example:
987+
* <pre>{@code
988+
* List<UpsertRecord> records = new ArrayList<>();
989+
* records.add(new UpsertRecord("rec1", "Apple's first product, the Apple I, was released in 1976.", "product"));
990+
* records.add(new UpsertRecord("rec2", "Apples are a great source of dietary fiber.", "nutrition"));
991+
*
992+
* try {
993+
* index.upsertRecords("example-namespace", records);
994+
* } catch (ApiException e) {
995+
*
996+
* }
997+
* }</pre></p>
998+
*
999+
* @param namespace The namespace within the Pinecone index where the records will be upserted.
1000+
* The namespace must be an existing namespace or a valid one to create new records.
1001+
* @param upsertRecord A list of {@link UpsertRecord} objects containing the records to be upserted.
1002+
* Each record must include a unique ID and the data to be stored.
1003+
* @throws ApiException If there is an issue with the upsert operation. This could include network errors,
1004+
* invalid input data, or issues communicating with the Pinecone service.
1005+
*/
9771006
public void upsertRecords(String namespace, List<UpsertRecord> upsertRecord) throws ApiException {
9781007
vectorOperations.upsertRecordsNamespace(namespace, upsertRecord);
9791008
}
9801009

981-
public SearchRecordsResponse searchRecords(String id, String namespace, Object filter, int topK, SearchRecordsVector vector) throws ApiException {
982-
SearchRecordsRequestQuery searchRecordsRequestquery = new SearchRecordsRequestQuery()
983-
.id(id)
984-
.filter(filter)
985-
.topK(topK)
986-
.vector(vector);
987-
SearchRecordsRequest request = new SearchRecordsRequest().query(searchRecordsRequestquery);
1010+
/**
1011+
* <p>Searches for records in a specified namespace within a Pinecone index by converting a query into a vector embedding.
1012+
* Optionally, a reranking operation can be applied to refine the results.</p>
1013+
*
1014+
* <p>This method sends a search query along with specified fields to the Pinecone index, retrieves the relevant records,
1015+
* and applies an optional reranking operation if provided.</p>
1016+
*
1017+
* <p>Example:
1018+
* <pre>{@code
1019+
* String namespace = "example-namespace";
1020+
* HashMap<String, String> inputsMap = new HashMap<>();
1021+
* inputsMap.put("text", "Disease prevention");
1022+
* SearchRecordsRequestQuery query = new SearchRecordsRequestQuery()
1023+
* .topK(3)
1024+
* .inputs(inputsMap);
1025+
*
1026+
* List<String> fields = new ArrayList<>();
1027+
* fields.add("category");
1028+
* fields.add("chunk_text");
1029+
*
1030+
* SearchRecordsResponse recordsResponse = index.searchRecords(namespace, query, fields, null);
1031+
* }</pre></p>
1032+
*
1033+
* @param namespace The namespace within the Pinecone index where the search will be performed.
1034+
* The namespace must exist and contain records to search through.
1035+
* @param query The query to be converted into a vector embedding for the search operation.
1036+
* This query contains the input data for the search and parameters like topK for result limits.
1037+
* @param fields A list of fields to be searched within the records. These fields define which parts of the records
1038+
* are considered during the search.
1039+
* @param rerank (Optional) A reranking operation that can be applied to refine or reorder the search results.
1040+
* Pass null if no reranking is required.
1041+
* @return A {@link SearchRecordsResponse} object containing the search results, including the top matching records.
1042+
* @throws ApiException If there is an issue with the search operation. This could include network errors,
1043+
* invalid input data, or issues communicating with the Pinecone service.
1044+
*/
1045+
public SearchRecordsResponse searchRecords(String namespace,
1046+
SearchRecordsRequestQuery query,
1047+
List<String> fields,
1048+
SearchRecordsRequestRerank rerank) throws ApiException {
1049+
SearchRecordsRequest request = new SearchRecordsRequest()
1050+
.query(query)
1051+
.fields(fields)
1052+
.rerank(rerank);
9881053

9891054
return vectorOperations.searchRecordsNamespace(namespace, request);
9901055
}

src/main/java/io/pinecone/clients/Pinecone.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ public IndexModel createSparseServelessIndex(String indexName,
221221
* Example:
222222
* <pre>{@code
223223
* client.createIndexForModel("my-index", CreateIndexForModelRequest.CloudEnum.AWS,
224-
* "us-west-2", embedConfig, DeletionProtection.ENABLED, tags);
224+
* "us-west-2", embedConfig, DeletionProtection.DISABLED, tags);
225225
* }</pre>
226226
*
227227
* @param name The name of the index to be created. The name must be between 1 and 45 characters,
@@ -993,8 +993,11 @@ public Index getIndexConnection(String indexName) throws PineconeValidationExcep
993993
throw new PineconeValidationException("Index name cannot be null or empty");
994994
}
995995

996-
PineconeConnection connection = getConnection(indexName);
997-
return new Index(config, connection, indexName);
996+
PineconeConfig perConnectionConfig = new PineconeConfig(config.getApiKey(), config.getSourceTag());
997+
perConnectionConfig.setHost(getIndexHost(indexName));
998+
999+
PineconeConnection connection = getConnection(indexName, perConnectionConfig);
1000+
return new Index(perConnectionConfig, connection, indexName);
9981001
}
9991002

10001003
/**
@@ -1022,7 +1025,10 @@ public AsyncIndex getAsyncIndexConnection(String indexName) throws PineconeValid
10221025
throw new PineconeValidationException("Index name cannot be null or empty");
10231026
}
10241027

1025-
PineconeConnection connection = getConnection(indexName);
1028+
PineconeConfig perConnectionConfig = new PineconeConfig(config.getApiKey(), config.getSourceTag());
1029+
perConnectionConfig.setHost(getIndexHost(indexName));
1030+
1031+
PineconeConnection connection = getConnection(indexName, perConnectionConfig);
10261032
return new AsyncIndex(config, connection, indexName);
10271033
}
10281034

@@ -1038,9 +1044,7 @@ public Inference getInferenceClient() {
10381044
return new Inference(config);
10391045
}
10401046

1041-
PineconeConnection getConnection(String indexName) {
1042-
PineconeConfig perConnectionConfig = new PineconeConfig(config.getApiKey(), config.getSourceTag());
1043-
perConnectionConfig.setHost(getIndexHost(indexName));
1047+
PineconeConnection getConnection(String indexName, PineconeConfig perConnectionConfig) {
10441048
return connectionsMap.computeIfAbsent(indexName, key -> new PineconeConnection(perConnectionConfig));
10451049
}
10461050

0 commit comments

Comments
 (0)