This version of the Pinecone Java SDK introduces indexes with integrated inference, backups and restore, and ability to work more explicitly with namespaces. It also supports version 2025-04
of the Pinecone API. You can read more about versioning here.
Features
Indexes with Integrated Inference
This release adds the following method for integrated inference. Together these methods provide a way for you to easily store your data and let us manage the process of creating embeddings. To learn about available models, see the Model Gallery.
- Create index for model i.e. create an index with an associated embedding model
- Configure an existing index to associate it with an embedding model
- Upsert records
- Search records by id
- Search records by vector
- Search records by text
import io.pinecone.clients.Index;
import io.pinecone.clients.Pinecone;
import io.pinecone.helpers.RandomStringBuilder;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openapitools.db_control.client.model.CreateIndexForModelRequest;
import org.openapitools.db_control.client.model.CreateIndexForModelRequestEmbed;
import org.openapitools.db_control.client.model.DeletionProtection;
import org.openapitools.db_data.client.ApiException;
import org.openapitools.db_data.client.model.SearchRecordsRequestQuery;
import org.openapitools.db_data.client.model.SearchRecordsResponse;
import org.openapitools.db_data.client.model.UpsertRecord;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
...
Pinecone pinecone = new Pinecone.Builder(System.getenv("PINECONE_API_KEY")).build();
String indexName = RandomStringBuilder.build("inf", 8);
// Create index associated with a model
HashMap<String, String> fieldMap = new HashMap<>();
fieldMap.put("text", "chunk_text");
CreateIndexForModelRequestEmbed embed = new CreateIndexForModelRequestEmbed()
.model("multilingual-e5-large")
.fieldMap(fieldMap);
pinecone.createIndexForModel(indexName, CreateIndexForModelRequest.CloudEnum.AWS, "us-west-2", embed, DeletionProtection.DISABLED, new HashMap<>());
// Wait for index to be created
Thread.sleep(10000);
Index index = pinecone.getIndexConnection(indexName);
// Upsert records
HashMap<String, String> record1 = new HashMap<>();
record1.put("_id", "rec1");
record1.put("category", "digestive system");
record1.put("chunk_text", "Apples are a great source of dietary fiber, which supports digestion and helps maintain a healthy gut.");
HashMap<String, String> record2 = new HashMap<>();
record2.put("_id", "rec2");
record2.put("category", "cultivation");
record2.put("chunk_text", "Apples originated in Central Asia and have been cultivated for thousands of years, with over 7,500 varieties available today.");
HashMap<String, String> record3 = new HashMap<>();
record3.put("_id", "rec3");
record3.put("category", "immune system");
record3.put("chunk_text", "Rich in vitamin C and other antioxidants, apples contribute to immune health and may reduce the risk of chronic diseases.");
HashMap<String, String> record4 = new HashMap<>();
record4.put("_id", "rec4");
record4.put("category", "endocrine system");
record4.put("chunk_text", "The high fiber content in apples can also help regulate blood sugar levels, making them a favorable snack for people with diabetes.");
upsertRecords.add(record1);
upsertRecords.add(record2);
upsertRecords.add(record3);
upsertRecords.add(record4);
index.upsertRecords("example-namespace", upsertRecords);
// Wait for vectors to be upserted
Thread.sleep(5000);
String namespace = "example-namespace";
List<String> fields = new ArrayList<>();
fields.add("category");
fields.add("chunk_text");
SearchRecordsRequestRerank rerank = new SearchRecordsRequestRerank()
.model("bge-reranker-v2-m3")
.topN(2)
.rankFields(Arrays.asList("chunk_text"));
// Search records
SearchRecordsResponse recordsResponse = index.searchRecordsByText("Disease prevention", namespace, fields, 4, null, rerank);
System.out.println(recordsResponse);
Backups and restore
You can now create and manage backups of serverless indexes. It is a static, non-queryable copy of an index that represents a set of records. You can create a backup of a serverless index, and you can create a new serverless index from a backup. You can read more about backups here.
Following methods were added for Backups:
- createBackup(String indexName, String backupName, String description)
- listIndexBackups(String indexName)
- listIndexBackups(String indexName, Integer limit, String paginationToken)
- listProjectBackups()
- describeBackup(String backupId)
- deleteBackup(String backupId)
- createIndexFromBackup(String backupId,
- String indexName,
- Map<String, String> tags,
- DeletionProtection deletionProtection)
- CreateIndexFromBackupResponse createIndexFromBackup(String backupId, String indexName)
Following methods were added for Restore:
- describeRestoreJob(String jobId)
- listRestoreJobs(Integer limit)
- listRestoreJobs(String paginationToken)
- listRestoreJobs(Integer limit, String paginationToken)
Below code shows all of the methods added for backup and restore for a serverless index.
import io.pinecone.clients.Pinecone;
import org.openapitools.db_control.client.ApiException;
import org.openapitools.db_control.client.model.*;
...
Pinecone pinecone = new Pinecone.Builder("PINECONE_API_KEY").build();
String indexName1 = "test-index-1";
String indexName2 = "test-index-2";
// create a backup from index
BackupModel backupModel1 = pinecone.createBackup(indexName1, "backup-id-1", "description-for-backup-1");
System.out.println("backupModel1: " + backupModel1);
BackupModel backupModel2 = pinecone.createBackup(indexName2, "backup-id-2", "description-for-backup-2");
System.out.println("backupModel2: " + backupModel2);
// list all backups for an index
BackupList backupList = pinecone.listIndexBackups(indexName1);
System.out.println("backupList for index1: " + backupList);
// list all backups for a project
backupList = pinecone.listProjectBackups();
System.out.println("backupList for project: " + backupList);
// describe backup
backupModel1 = pinecone.describeBackup(backupModel1.getBackupId());
System.out.println("describe backup for index1: " + backupModel1);
backupModel2 = pinecone.describeBackup(backupModel2.getBackupId());
System.out.println("describe backup index2: " + backupModel2);
// delete backup
pinecone.deleteBackup(backupModel1.getBackupId());
// wait for the backup to be ready
Thread.sleep(10000);
// create index from a backup
CreateIndexFromBackupResponse backupResponse = pinecone.createIndexFromBackup(backupModel1.getBackupId(), "test-index-3");
System.out.println(backupResponse.getRestoreJobId());
// wait for index to be created
Thread.sleep(5000);
// describeRestoreJob
RestoreJobModel restoreJobModel = pinecone.describeRestoreJob(backupResponse.getRestoreJobId());
System.out.println("restore model: " + restoreJobModel);
// listRestoreJobs
RestoreJobList restoreJobList = pinecone.listRestoreJobs(2);
System.out.println("restore job list: " + restoreJobList);
Namespaces
You now have the ability to work more explicitly with namespaces that are associated with an index. There have been several namespace methods added to the Index class:
- listNamespaces()
- listNamespaces(String paginationToken)
- listNamespaces(String paginationToken, int limit)
- describeNamespace(String namespace)
- deleteNamespace(String namespace)
Following example shows listNamespaces(), describeNamespace(), and deleteNamespace() methods for both index and asyncIndex.
import io.pinecone.clients.AsyncIndex;
import io.pinecone.clients.Index;
import io.pinecone.clients.Pinecone;
import io.pinecone.proto.ListNamespacesResponse;
import io.pinecone.proto.NamespaceDescription;
import java.util.concurrent.ExecutionException;
...
String indexName = "PINECONE_INDEX_NAME";
Pinecone pinecone = new Pinecone.Builder("PINECONE_API_KEY").build();
//// Sync index example
Index index = pinecone.getIndexConnection(indexName);
// list namespaces without pagination token and limit (if no limit is passed, it'll default to 100)
ListNamespacesResponse listNamespacesResponse = index.listNamespaces();
// list namespaces with pagination token
listNamespacesResponse = index.listNamespaces("some-pagination-token");
// list namespaces with pagination token and a custom limit of 5
listNamespacesResponse = index.listNamespaces("some-pagination-token", 5);
// describe a namespace
NamespaceDescription namespaceDescription = index.describeNamespace("namespace");
// delete a namespace
index.deleteNamespace("namespace");
//// AsyncIndex example
AsyncIndex asyncIndex = pinecone.getAsyncIndexConnection(indexName);
// list namespaces without pagination token and limit (if no limit is passed, it'll default to 100)
ListNamespacesResponse asyncListNamespacesResponse = index.listNamespaces();
// list namespaces with pagination token
asyncListNamespacesResponse = asyncIndex.listNamespaces("some-pagination-token").get();
// list namespaces with pagination token and a custom limit of 5
asyncListNamespacesResponse = asyncIndex.listNamespaces("some-pagination-token", 5).get();
// describe a namespace
NamespaceDescription asyncNamespaceDescription = asyncIndex.describeNamespace("some-namespace").get();
// delete a namespace
asyncIndex.deleteNamespace("some-namespace");
What's Changed
- Add integrated inference by @rohanshah18 in #181
- Generate code for 2025-04, automate ndjson handling, add backups, restore, and namespaces. by @rohanshah18 in #183
Full Changelog: v4.0.1...v5.0.0