From 0a387f547a2928c4a0149eba785c0ff0fbd2bf28 Mon Sep 17 00:00:00 2001 From: rohanshah18 Date: Wed, 12 Nov 2025 14:35:24 -0500 Subject: [PATCH 1/2] add support for creating a namespace --- README.md | 30 +++++++++++++++ .../integration/dataPlane/NamespacesTest.java | 32 ++++++++++++---- .../java/io/pinecone/clients/AsyncIndex.java | 37 +++++++++++++++++++ src/main/java/io/pinecone/clients/Index.java | 37 +++++++++++++++++++ .../io/pinecone/commons/IndexInterface.java | 19 ++++++++++ 5 files changed, 147 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 44e74176..2092a607 100644 --- a/README.md +++ b/README.md @@ -697,6 +697,36 @@ List values = Arrays.asList(1F, 2F, 3F); UpdateResponse updateResponse = index.update("v1", values, "example-namespace"); ``` +## Create namespace + +The following example shows how to create a namespace. + +```java +import io.pinecone.clients.AsyncIndex; +import io.pinecone.clients.Index; +import io.pinecone.clients.Pinecone; +import io.pinecone.proto.MetadataFieldProperties; +import io.pinecone.proto.MetadataSchema; +import io.pinecone.proto.NamespaceDescription; + +import java.util.concurrent.ExecutionException; +... + +String indexName = "PINECONE_INDEX_NAME"; +Pinecone pinecone = new Pinecone.Builder("PINECONE_API_KEY").build(); +Index index = pinecone.getIndexConnection(indexName); + +// create a namespace +NamespaceDescription namespaceDescription = index.createNamespace("some-namespace"); + +// create a namespace with metadata schema +MetadataSchema schema = MetadataSchema.newBuilder() + .putFields("genre", MetadataFieldProperties.newBuilder().setFilterable(true).build()) + .putFields("year", MetadataFieldProperties.newBuilder().setFilterable(true).build()) + .build(); +NamespaceDescription namespaceWithSchema = index.createNamespace("some-namespace", schema); +``` + ## List namespaces The following example shows various methods to list namespaces. diff --git a/src/integration/java/io/pinecone/integration/dataPlane/NamespacesTest.java b/src/integration/java/io/pinecone/integration/dataPlane/NamespacesTest.java index 5ed28256..38da5a40 100644 --- a/src/integration/java/io/pinecone/integration/dataPlane/NamespacesTest.java +++ b/src/integration/java/io/pinecone/integration/dataPlane/NamespacesTest.java @@ -5,6 +5,7 @@ import io.pinecone.helpers.RandomStringBuilder; import io.pinecone.helpers.TestResourcesManager; import io.pinecone.proto.ListNamespacesResponse; +import io.pinecone.proto.NamespaceDescription; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; @@ -12,6 +13,7 @@ import static io.pinecone.helpers.BuildUpsertRequest.generateVectorValuesByDimension; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; public class NamespacesTest { private static final TestResourcesManager indexManager = TestResourcesManager.getInstance(); @@ -27,12 +29,19 @@ public static void cleanUp() { @Test public void namespacesSyncTest() throws InterruptedException { - String[] namespaces = new String[3]; + String[] namespaces = new String[4]; index = indexManager.getOrCreateServerlessIndexConnection(); ListNamespacesResponse listNamespacesResponse = index.listNamespaces(); int namespaceCount = listNamespacesResponse.getNamespacesCount(); - for(int i=0; i<3; i++) { + // Create namespace explicitly using createNamespace + namespaces[0] = RandomStringBuilder.build("namespace-", 3); + NamespaceDescription createdNamespace = index.createNamespace(namespaces[0]); + assertNotNull(createdNamespace); + assertEquals(namespaces[0], createdNamespace.getName()); + + // Create namespaces implicitly by upserting vectors + for(int i=1; i<4; i++) { namespaces[i] = RandomStringBuilder.build("namespace-", 3); index.upsert("v"+i, generateVectorValuesByDimension(dimension), namespaces[i]); } @@ -40,7 +49,7 @@ public void namespacesSyncTest() throws InterruptedException { // wait for vectors to be upserted Thread.sleep(5000); listNamespacesResponse = index.listNamespaces(); - assertEquals(listNamespacesResponse.getNamespacesCount(), namespaceCount + 3); + assertEquals(listNamespacesResponse.getNamespacesCount(), namespaceCount + 4); index.describeNamespace(namespaces[0]); index.deleteNamespace(namespaces[0]); @@ -48,18 +57,25 @@ public void namespacesSyncTest() throws InterruptedException { // wait for namespace to be deleted Thread.sleep(3000); listNamespacesResponse = index.listNamespaces(); - assertEquals(listNamespacesResponse.getNamespacesCount(), namespaceCount + 2); + assertEquals(listNamespacesResponse.getNamespacesCount(), namespaceCount + 3); } @Test public void namespacesAsyncTest() throws InterruptedException, ExecutionException { - String[] namespaces = new String[3]; + String[] namespaces = new String[4]; asyncIndex = indexManager.getOrCreateServerlessAsyncIndexConnection(); ListNamespacesResponse listNamespacesResponse = asyncIndex.listNamespaces().get(); int namespaceCount = listNamespacesResponse.getNamespacesCount(); - for(int i=0; i<3; i++) { + // Create namespace explicitly using createNamespace + namespaces[0] = RandomStringBuilder.build("namespace-", 3); + NamespaceDescription createdNamespace = asyncIndex.createNamespace(namespaces[0]).get(); + assertNotNull(createdNamespace); + assertEquals(namespaces[0], createdNamespace.getName()); + + // Create namespaces implicitly by upserting vectors + for(int i=1; i<4; i++) { namespaces[i] = RandomStringBuilder.build("namespace-", 3); asyncIndex.upsert("v"+i, generateVectorValuesByDimension(dimension), namespaces[i]); } @@ -67,7 +83,7 @@ public void namespacesAsyncTest() throws InterruptedException, ExecutionExceptio // wait for vectors to be upserted Thread.sleep(5000); listNamespacesResponse = asyncIndex.listNamespaces().get(); - assertEquals(listNamespacesResponse.getNamespacesCount(), namespaceCount + 3); + assertEquals(listNamespacesResponse.getNamespacesCount(), namespaceCount + 4); asyncIndex.describeNamespace(namespaces[0]); asyncIndex.deleteNamespace(namespaces[0]); @@ -75,6 +91,6 @@ public void namespacesAsyncTest() throws InterruptedException, ExecutionExceptio // wait for namespace to be deleted Thread.sleep(3000); listNamespacesResponse = asyncIndex.listNamespaces().get(); - assertEquals(listNamespacesResponse.getNamespacesCount(), namespaceCount + 2); + assertEquals(listNamespacesResponse.getNamespacesCount(), namespaceCount + 3); } } diff --git a/src/main/java/io/pinecone/clients/AsyncIndex.java b/src/main/java/io/pinecone/clients/AsyncIndex.java index 3b221a70..d010cb0b 100644 --- a/src/main/java/io/pinecone/clients/AsyncIndex.java +++ b/src/main/java/io/pinecone/clients/AsyncIndex.java @@ -9,11 +9,13 @@ import io.pinecone.configs.PineconeConnection; import io.pinecone.exceptions.PineconeValidationException; import io.pinecone.proto.*; +import io.pinecone.proto.CreateNamespaceRequest; import io.pinecone.proto.DeleteRequest; import io.pinecone.proto.DescribeIndexStatsRequest; import io.pinecone.proto.FetchResponse; import io.pinecone.proto.ListNamespacesResponse; import io.pinecone.proto.ListResponse; +import io.pinecone.proto.MetadataSchema; import io.pinecone.proto.NamespaceDescription; import io.pinecone.proto.QueryRequest; import io.pinecone.proto.QueryResponse; @@ -1124,6 +1126,41 @@ public ListenableFuture listNamespaces(String pagination return asyncStub.listNamespaces(listNamespacesRequest.build()); } + /** + *
+     * Create a namespace within an index.
+     * @param name The name of the namespace to create.
+     * @return {@link ListenableFuture} The response for the create namespace operation.
+     * 
+ */ + @Override + public ListenableFuture createNamespace(String name) { + CreateNamespaceRequest createNamespaceRequest = CreateNamespaceRequest + .newBuilder() + .setName(name) + .build(); + return asyncStub.createNamespace(createNamespaceRequest); + } + + /** + *
+     * Create a namespace within an index with a metadata schema.
+     * @param name The name of the namespace to create.
+     * @param schema The metadata schema for the namespace.
+     * @return {@link ListenableFuture} The response for the create namespace operation.
+     * 
+ */ + @Override + public ListenableFuture createNamespace(String name, MetadataSchema schema) { + CreateNamespaceRequest.Builder builder = CreateNamespaceRequest + .newBuilder() + .setName(name); + if (schema != null) { + builder.setSchema(schema); + } + return asyncStub.createNamespace(builder.build()); + } + /** *
      * Describe a namespace within an index, showing the vector count within the namespace.
diff --git a/src/main/java/io/pinecone/clients/Index.java b/src/main/java/io/pinecone/clients/Index.java
index c62ab93f..b2b18701 100644
--- a/src/main/java/io/pinecone/clients/Index.java
+++ b/src/main/java/io/pinecone/clients/Index.java
@@ -6,11 +6,13 @@
 import io.pinecone.configs.PineconeConnection;
 import io.pinecone.exceptions.PineconeValidationException;
 import io.pinecone.proto.*;
+import io.pinecone.proto.CreateNamespaceRequest;
 import io.pinecone.proto.DeleteRequest;
 import io.pinecone.proto.DescribeIndexStatsRequest;
 import io.pinecone.proto.FetchResponse;
 import io.pinecone.proto.ListNamespacesResponse;
 import io.pinecone.proto.ListResponse;
+import io.pinecone.proto.MetadataSchema;
 import io.pinecone.proto.NamespaceDescription;
 import io.pinecone.proto.QueryRequest;
 import io.pinecone.proto.UpdateRequest;
@@ -1034,6 +1036,41 @@ public ListNamespacesResponse listNamespaces(String paginationToken, int limit)
         return blockingStub.listNamespaces(listNamespacesRequest.build());
     }
 
+    /**
+     * 
+     * Create a namespace within an index.
+     * @param name The name of the namespace to create.
+     * @return {@link NamespaceDescription} The response for the create namespace operation.
+     * 
+ */ + @Override + public NamespaceDescription createNamespace(String name) { + CreateNamespaceRequest createNamespaceRequest = CreateNamespaceRequest + .newBuilder() + .setName(name) + .build(); + return blockingStub.createNamespace(createNamespaceRequest); + } + + /** + *
+     * Create a namespace within an index with a metadata schema.
+     * @param name The name of the namespace to create.
+     * @param schema The metadata schema for the namespace.
+     * @return {@link NamespaceDescription} The response for the create namespace operation.
+     * 
+ */ + @Override + public NamespaceDescription createNamespace(String name, MetadataSchema schema) { + CreateNamespaceRequest.Builder builder = CreateNamespaceRequest + .newBuilder() + .setName(name); + if (schema != null) { + builder.setSchema(schema); + } + return blockingStub.createNamespace(builder.build()); + } + /** *
      * Describe a namespace within an index, showing the vector count within the namespace.
diff --git a/src/main/java/io/pinecone/commons/IndexInterface.java b/src/main/java/io/pinecone/commons/IndexInterface.java
index e7e1eb78..de9e4489 100644
--- a/src/main/java/io/pinecone/commons/IndexInterface.java
+++ b/src/main/java/io/pinecone/commons/IndexInterface.java
@@ -854,6 +854,25 @@ default void validateListEndpointParameters(String namespace, String prefix, Str
      */
     A listNamespaces(String paginationToken, int limit);
 
+    /**
+     * 
+     * Create a namespace within an index.
+     * @param name The name of the namespace to create.
+     * @return {@link NamespaceDescription} The response for the create namespace operation.
+     * 
+ */ + B createNamespace(String name); + + /** + *
+     * Create a namespace within an index with a metadata schema.
+     * @param name The name of the namespace to create.
+     * @param schema The metadata schema for the namespace.
+     * @return {@link NamespaceDescription} The response for the create namespace operation.
+     * 
+ */ + B createNamespace(String name, io.pinecone.proto.MetadataSchema schema); + /** *
      * Describe a namespace within an index, showing the vector count within the namespace.

From 4c40f786212a6e83c308c58192b0f5856318c028 Mon Sep 17 00:00:00 2001
From: rohanshah18 
Date: Wed, 12 Nov 2025 15:26:06 -0500
Subject: [PATCH 2/2] add prefix filtering and total count to listNamespaces()

---
 README.md                                     | 13 ++++++
 .../integration/dataPlane/NamespacesTest.java | 43 +++++++++++++++++--
 .../java/io/pinecone/clients/AsyncIndex.java  | 25 +++++++++++
 src/main/java/io/pinecone/clients/Index.java  | 25 +++++++++++
 .../io/pinecone/commons/IndexInterface.java   | 13 ++++++
 5 files changed, 116 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 2092a607..d402d9ad 100644
--- a/README.md
+++ b/README.md
@@ -752,6 +752,19 @@ listNamespacesResponse = index.listNamespaces("some-pagination-token");
 
 // list namespaces with pagination token and a custom limit of 5
 listNamespacesResponse = index.listNamespaces("some-pagination-token", 5);
+
+// The totalCount field returns the total number of namespaces in the index
+// When prefix filtering is used, it returns the count of namespaces matching the prefix
+int totalCount = listNamespacesResponse.getTotalCount();
+
+// list namespaces with prefix filtering
+// Prefix filtering allows you to filter namespaces that start with a specific prefix
+listNamespacesResponse = index.listNamespaces("test-", null, 10);
+totalCount = listNamespacesResponse.getTotalCount(); // Total count of namespaces matching "test-" prefix
+
+// list namespaces with prefix, pagination token, and limit
+listNamespacesResponse = index.listNamespaces("test-", "some-pagination-token", 10);
+totalCount = listNamespacesResponse.getTotalCount();
 ```
 
 ## Describe namespace
diff --git a/src/integration/java/io/pinecone/integration/dataPlane/NamespacesTest.java b/src/integration/java/io/pinecone/integration/dataPlane/NamespacesTest.java
index 38da5a40..dfd61de8 100644
--- a/src/integration/java/io/pinecone/integration/dataPlane/NamespacesTest.java
+++ b/src/integration/java/io/pinecone/integration/dataPlane/NamespacesTest.java
@@ -14,6 +14,7 @@
 import static io.pinecone.helpers.BuildUpsertRequest.generateVectorValuesByDimension;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class NamespacesTest {
     private static final TestResourcesManager indexManager = TestResourcesManager.getInstance();
@@ -41,7 +42,7 @@ public void namespacesSyncTest() throws InterruptedException {
         assertEquals(namespaces[0], createdNamespace.getName());
 
         // Create namespaces implicitly by upserting vectors
-        for(int i=1; i<4; i++) {
+        for (int i=1; i<4; i++) {
             namespaces[i] = RandomStringBuilder.build("namespace-", 3);
             index.upsert("v"+i, generateVectorValuesByDimension(dimension), namespaces[i]);
         }
@@ -58,6 +59,24 @@ public void namespacesSyncTest() throws InterruptedException {
         Thread.sleep(3000);
         listNamespacesResponse = index.listNamespaces();
         assertEquals(listNamespacesResponse.getNamespacesCount(), namespaceCount + 3);
+
+        // Test prefix filtering and total count
+        String prefix = "namespace-";
+        ListNamespacesResponse prefixResponse = index.listNamespaces(prefix, null, 100);
+        assertNotNull(prefixResponse);
+        assertTrue(prefixResponse.getTotalCount() >= 3, "totalCount should be at least 3");
+        assertTrue(prefixResponse.getNamespacesCount() >= 3, "Should return at least 3 namespaces with prefix");
+        
+        // Verify all returned namespaces start with the prefix
+        for (int i = 0; i < prefixResponse.getNamespacesCount(); i++) {
+            String namespaceName = prefixResponse.getNamespaces(i).getName();
+            assertTrue(namespaceName.startsWith(prefix), 
+                "Namespace " + namespaceName + " should start with prefix " + prefix);
+        }
+        
+        // Verify totalCount is at least the number of namespaces returned
+        assertTrue(prefixResponse.getTotalCount() >= prefixResponse.getNamespacesCount(),
+            "totalCount should be at least equal to the number of namespaces returned");
     }
 
     @Test
@@ -75,7 +94,7 @@ public void namespacesAsyncTest() throws InterruptedException, ExecutionExceptio
         assertEquals(namespaces[0], createdNamespace.getName());
 
         // Create namespaces implicitly by upserting vectors
-        for(int i=1; i<4; i++) {
+        for (int i=1; i<4; i++) {
             namespaces[i] = RandomStringBuilder.build("namespace-", 3);
             asyncIndex.upsert("v"+i, generateVectorValuesByDimension(dimension), namespaces[i]);
         }
@@ -92,5 +111,23 @@ public void namespacesAsyncTest() throws InterruptedException, ExecutionExceptio
         Thread.sleep(3000);
         listNamespacesResponse = asyncIndex.listNamespaces().get();
         assertEquals(listNamespacesResponse.getNamespacesCount(), namespaceCount + 3);
+
+        // Test prefix filtering and total count
+        String prefix = "namespace-";
+        ListNamespacesResponse prefixResponse = asyncIndex.listNamespaces(prefix, null, 100).get();
+        assertNotNull(prefixResponse);
+        assertTrue(prefixResponse.getTotalCount() >= 3, "totalCount should be at least 3");
+        assertTrue(prefixResponse.getNamespacesCount() >= 3, "Should return at least 3 namespaces with prefix");
+        
+        // Verify all returned namespaces start with the prefix
+        for (int i = 0; i < prefixResponse.getNamespacesCount(); i++) {
+            String namespaceName = prefixResponse.getNamespaces(i).getName();
+            assertTrue(namespaceName.startsWith(prefix),
+                "Namespace " + namespaceName + " should start with prefix " + prefix);
+        }
+        
+        // Verify totalCount is at least the number of namespaces returned
+        assertTrue(prefixResponse.getTotalCount() >= prefixResponse.getNamespacesCount(),
+            "totalCount should be at least equal to the number of namespaces returned");
     }
-}
+}
\ No newline at end of file
diff --git a/src/main/java/io/pinecone/clients/AsyncIndex.java b/src/main/java/io/pinecone/clients/AsyncIndex.java
index d010cb0b..688deb43 100644
--- a/src/main/java/io/pinecone/clients/AsyncIndex.java
+++ b/src/main/java/io/pinecone/clients/AsyncIndex.java
@@ -1126,6 +1126,31 @@ public ListenableFuture listNamespaces(String pagination
         return asyncStub.listNamespaces(listNamespacesRequest.build());
     }
 
+    /**
+     * 
+     * Get list of all namespaces within an index with optional prefix filtering, pagination token, and limit.
+     * @param prefix The prefix to filter namespaces by. Only namespaces starting with this prefix will be returned.
+     *               If null, no prefix filtering is applied.
+     * @param paginationToken The token to paginate through the list of namespaces. If null, it'll be ignored.
+     * @param limit The maximum number of namespaces you want to retrieve.
+     * @return {@link ListenableFuture} The response for the list namespace operation. The totalCount field
+     *         indicates the total number of namespaces matching the prefix (if provided).
+     * 
+ */ + @Override + public ListenableFuture listNamespaces(String prefix, String paginationToken, int limit) { + ListNamespacesRequest.Builder listNamespacesRequest = ListNamespacesRequest + .newBuilder() + .setLimit(limit); + if(prefix != null && !prefix.isEmpty()) { + listNamespacesRequest.setPrefix(prefix); + } + if(paginationToken != null) { + listNamespacesRequest.setPaginationToken(paginationToken); + } + return asyncStub.listNamespaces(listNamespacesRequest.build()); + } + /** *
      * Create a namespace within an index.
diff --git a/src/main/java/io/pinecone/clients/Index.java b/src/main/java/io/pinecone/clients/Index.java
index b2b18701..48c5adb1 100644
--- a/src/main/java/io/pinecone/clients/Index.java
+++ b/src/main/java/io/pinecone/clients/Index.java
@@ -1036,6 +1036,31 @@ public ListNamespacesResponse listNamespaces(String paginationToken, int limit)
         return blockingStub.listNamespaces(listNamespacesRequest.build());
     }
 
+    /**
+     * 
+     * Get list of all namespaces within an index with optional prefix filtering, pagination token, and limit.
+     * @param prefix The prefix to filter namespaces by. Only namespaces starting with this prefix will be returned.
+     *               If null, no prefix filtering is applied.
+     * @param paginationToken The token to paginate through the list of namespaces. If null, it'll be ignored.
+     * @param limit The maximum number of namespaces you want to retrieve.
+     * @return {@link ListNamespacesResponse} The response for the list namespace operation. The totalCount field
+     *         indicates the total number of namespaces matching the prefix (if provided).
+     * 
+ */ + @Override + public ListNamespacesResponse listNamespaces(String prefix, String paginationToken, int limit) { + ListNamespacesRequest.Builder listNamespacesRequest = ListNamespacesRequest + .newBuilder() + .setLimit(limit); + if(prefix != null && !prefix.isEmpty()) { + listNamespacesRequest.setPrefix(prefix); + } + if(paginationToken != null) { + listNamespacesRequest.setPaginationToken(paginationToken); + } + return blockingStub.listNamespaces(listNamespacesRequest.build()); + } + /** *
      * Create a namespace within an index.
diff --git a/src/main/java/io/pinecone/commons/IndexInterface.java b/src/main/java/io/pinecone/commons/IndexInterface.java
index de9e4489..ea8e9acc 100644
--- a/src/main/java/io/pinecone/commons/IndexInterface.java
+++ b/src/main/java/io/pinecone/commons/IndexInterface.java
@@ -854,6 +854,19 @@ default void validateListEndpointParameters(String namespace, String prefix, Str
      */
     A listNamespaces(String paginationToken, int limit);
 
+    /**
+     * 
+     * Get list of all namespaces within an index with optional prefix filtering, pagination token, and limit.
+     * @param prefix The prefix to filter namespaces by. Only namespaces starting with this prefix will be returned.
+     *               If null, no prefix filtering is applied.
+     * @param paginationToken The token to paginate through the list of namespaces. If null, it'll be ignored.
+     * @param limit The maximum number of namespaces you want to retrieve.
+     * @return {@link ListNamespacesResponse} The response for the list namespace operation. The totalCount field
+     *         indicates the total number of namespaces matching the prefix (if provided).
+     * 
+ */ + A listNamespaces(String prefix, String paginationToken, int limit); + /** *
      * Create a namespace within an index.