Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,105 @@ tags.put("env", "test");
IndexModel indexModel = pinecone.createServerlessIndex(indexName, similarityMetric, dimension, cloud, region, "enabled", tags);
```

### Create a serverless index with dedicated read capacity

The following example creates a serverless index with dedicated read capacity nodes for better performance and cost predictability. For more information, see [Dedicated Read Nodes](https://docs.pinecone.io/guides/index-data/dedicated-read-nodes).

```java
import io.pinecone.clients.Pinecone;
import org.openapitools.db_control.client.model.IndexModel;
import org.openapitools.db_control.client.model.ReadCapacity;
import org.openapitools.db_control.client.model.ReadCapacityDedicatedSpec;
import org.openapitools.db_control.client.model.ReadCapacityDedicatedConfig;
import org.openapitools.db_control.client.model.ScalingConfigManual;
import java.util.HashMap;
...

Pinecone pinecone = new Pinecone.Builder("PINECONE_API_KEY").build();

String indexName = "example-index";
String similarityMetric = "cosine";
int dimension = 1538;
String cloud = "aws";
String region = "us-west-2";
HashMap<String, String> tags = new HashMap<>();
tags.put("env", "test");

// Configure dedicated read capacity with manual scaling
ScalingConfigManual manual = new ScalingConfigManual().shards(2).replicas(2);
ReadCapacityDedicatedConfig dedicated = new ReadCapacityDedicatedConfig()
.nodeType("t1")
.scaling("Manual")
.manual(manual);
ReadCapacity readCapacity = new ReadCapacity(
new ReadCapacityDedicatedSpec().mode("Dedicated").dedicated(dedicated));

IndexModel indexModel = pinecone.createServerlessIndex(indexName, similarityMetric, dimension,
cloud, region, "enabled", tags, readCapacity, null);
```

### Create a serverless index with OnDemand read capacity

The following example explicitly creates a serverless index with OnDemand read capacity (the default mode). OnDemand provides pay-per-use pricing with automatic scaling.

```java
import io.pinecone.clients.Pinecone;
import org.openapitools.db_control.client.model.IndexModel;
import org.openapitools.db_control.client.model.ReadCapacity;
import org.openapitools.db_control.client.model.ReadCapacityOnDemandSpec;
import java.util.HashMap;
...

Pinecone pinecone = new Pinecone.Builder("PINECONE_API_KEY").build();

String indexName = "example-index";
String similarityMetric = "cosine";
int dimension = 1538;
String cloud = "aws";
String region = "us-west-2";
HashMap<String, String> tags = new HashMap<>();
tags.put("env", "test");

// Configure OnDemand read capacity (optional - this is the default)
ReadCapacity readCapacity = new ReadCapacity(new ReadCapacityOnDemandSpec().mode("OnDemand"));

IndexModel indexModel = pinecone.createServerlessIndex(indexName, similarityMetric, dimension,
cloud, region, "enabled", tags, readCapacity, null);
```

### Create a serverless index with metadata schema

The following example creates a serverless index with metadata schema configuration to limit metadata indexing to specific fields for improved performance.

```java
import io.pinecone.clients.Pinecone;
import org.openapitools.db_control.client.model.IndexModel;
import org.openapitools.db_control.client.model.BackupModelSchema;
import org.openapitools.db_control.client.model.BackupModelSchemaFieldsValue;
import java.util.HashMap;
...

Pinecone pinecone = new Pinecone.Builder("PINECONE_API_KEY").build();

String indexName = "example-index";
String similarityMetric = "cosine";
int dimension = 1538;
String cloud = "aws";
String region = "us-west-2";
HashMap<String, String> tags = new HashMap<>();
tags.put("env", "test");

// Configure metadata schema to only index specific fields
HashMap<String, BackupModelSchemaFieldsValue> fields = new HashMap<>();
fields.put("genre", new BackupModelSchemaFieldsValue().filterable(true));
fields.put("year", new BackupModelSchemaFieldsValue().filterable(true));
fields.put("description", new BackupModelSchemaFieldsValue().filterable(true));
BackupModelSchema schema = new BackupModelSchema().fields(fields);

IndexModel indexModel = pinecone.createServerlessIndex(indexName, similarityMetric, dimension,
cloud, region, "enabled", tags, null, schema);
```

### Create a sparse serverless index

The following is an example of creating a sparse serverless index in the `us-east-1` region of AWS. For more information on
Expand Down Expand Up @@ -341,6 +440,38 @@ tags.put("env", "test");
pinecone.configureServerlessIndex(indexName, "enabled", tags);
```

### Configure read capacity on an existing serverless index

The following example shows how to configure or change the read capacity mode of an existing serverless index. You can switch between OnDemand and Dedicated modes, or scale dedicated read nodes.

**Note:** Read capacity settings can only be updated once per hour per index.

```java
import io.pinecone.clients.Pinecone;
import org.openapitools.db_control.client.model.IndexModel;
import java.util.HashMap;
...

Pinecone pinecone = new Pinecone.Builder("PINECONE_API_KEY").build();

String indexName = "example-index";
HashMap<String, String> tags = new HashMap<>();
tags.put("env", "test");

// Switch to Dedicated read capacity with manual scaling
// Parameters: indexName, deletionProtection, tags, embed, readCapacityMode, nodeType, shards, replicas
IndexModel indexModel = pinecone.configureServerlessIndex(
indexName, "enabled", tags, null, "Dedicated", "t1", 3, 2);

// Switch to OnDemand read capacity
IndexModel onDemandIndex = pinecone.configureServerlessIndex(
indexName, "enabled", tags, null, "OnDemand", null, null, null);

// Verify the configuration was applied
IndexModel desc = pinecone.describeIndex(indexName);
// Check desc.getSpec().getServerless().getReadCapacity()...
```

## Describe index statistics

The following example returns statistics about an index.
Expand Down
75 changes: 75 additions & 0 deletions src/integration/java/io/pinecone/helpers/TestUtilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,81 @@ public static IndexModel waitUntilIndexIsReady(Pinecone pineconeClient, String i
return waitUntilIndexIsReady(pineconeClient, indexName, 200000);
}

/**
* Waits until the read capacity status is Ready for a serverless index.
* This is needed before configuring read capacity, as the API requires read capacity to be Ready before updates.
*
* @param pineconeClient The Pinecone client instance
* @param indexName The name of the index
* @param totalMsToWait Maximum time to wait in milliseconds
* @return The IndexModel with read capacity status Ready
* @throws InterruptedException if the thread is interrupted
*/
public static IndexModel waitUntilReadCapacityIsReady(Pinecone pineconeClient, String indexName, Integer totalMsToWait) throws InterruptedException {
IndexModel index = pineconeClient.describeIndex(indexName);
int waitedTimeMs = 0;
int intervalMs = 2000;

while (true) {
// Check if index has serverless spec with read capacity
if (index.getSpec() != null && index.getSpec().getIndexModelServerless() != null) {
ServerlessSpecResponse serverless = index.getSpec().getIndexModelServerless().getServerless();
if (serverless != null && serverless.getReadCapacity() != null) {
ReadCapacityResponse readCapacityResponse = serverless.getReadCapacity();
ReadCapacityStatus status = null;

// Get status from the appropriate response type
try {
ReadCapacityDedicatedSpecResponse dedicatedResponse = readCapacityResponse.getReadCapacityDedicatedSpecResponse();
status = dedicatedResponse.getStatus();
} catch (ClassCastException e) {
try {
ReadCapacityOnDemandSpecResponse onDemandResponse = readCapacityResponse.getReadCapacityOnDemandSpecResponse();
status = onDemandResponse.getStatus();
} catch (ClassCastException e2) {
logger.warn("Unknown read capacity response type for index " + indexName);
}
}

if (status != null && "Ready".equals(status.getState())) {
logger.info("Read capacity for index " + indexName + " is ready after " + waitedTimeMs + "ms");
break;
}
} else {
// If no read capacity is configured (OnDemand by default), consider it ready
logger.info("Index " + indexName + " has no read capacity configured (defaults to OnDemand), considering ready");
break;
}
} else {
// Not a serverless index or spec not available yet
logger.info("Index " + indexName + " spec not available yet, waiting...");
}

if (waitedTimeMs >= totalMsToWait) {
logger.info("WARNING: Read capacity for index " + indexName + " not ready after " + waitedTimeMs + "ms");
break;
}

Thread.sleep(intervalMs);
waitedTimeMs += intervalMs;
logger.info("Waited " + waitedTimeMs + "ms for read capacity of " + indexName + " to get ready");
index = pineconeClient.describeIndex(indexName);
}
return index;
}

/**
* Waits until the read capacity status is Ready for a serverless index (default timeout: 200 seconds).
*
* @param pineconeClient The Pinecone client instance
* @param indexName The name of the index
* @return The IndexModel with read capacity status Ready
* @throws InterruptedException if the thread is interrupted
*/
public static IndexModel waitUntilReadCapacityIsReady(Pinecone pineconeClient, String indexName) throws InterruptedException {
return waitUntilReadCapacityIsReady(pineconeClient, indexName, 200000);
}

public static CollectionModel createCollection(Pinecone pineconeClient, String collectionName, String indexName, boolean waitUntilReady) throws InterruptedException {
CollectionModel collection = pineconeClient.createCollection(collectionName, indexName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.pinecone.exceptions.PineconeForbiddenException;
import io.pinecone.exceptions.PineconeNotFoundException;
import io.pinecone.helpers.TestResourcesManager;
import okhttp3.OkHttpClient;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
Expand All @@ -13,6 +14,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

import static io.pinecone.helpers.AssertRetry.assertWithRetry;
import static org.junit.jupiter.api.Assertions.*;

Expand All @@ -22,6 +25,11 @@ public class ConfigureIndexTest {
private static final Pinecone controlPlaneClient = new Pinecone
.Builder(System.getenv("PINECONE_API_KEY"))
.withSourceTag("pinecone_test")
.withOkHttpClient(new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build())
.build();
private static String indexName;

Expand Down
Loading
Loading