Skip to content

Releases: pinecone-io/go-pinecone

Release v4.0.1

14 Jun 08:16
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v4.0.0...v4.0.1

Release v4.0.0

12 Jun 06:37
Compare
Choose a tag to compare

This version of the Pinecone Go SDK depends on version 2025-04 of the Pinecone API. You can read more about versioning here. This v4 SDK release line should continue to receive fixes as long as the 2025-04 API version is in support.

Features

Namespaces

You can now work directly with namespaces associated with a specific index. There have been three new methods added to the IndexConnection class allowing you to DescribeNamespace, ListNamespaces within an index, and DeleteNamespace. Currently, namespaces are still created implicitly when calling Upsert against a specific IndexConnection targeting a namespace.

Note: You can now use IndexConnection.WithNamespace to create a shallow copy of the gRPC connection targeting a different namespace which reuses the underlying connection internals. See "Bug fixes & Breaking Changes" below for more details.

import (
	"context"
	"log"

	"github.com/pinecone-io/go-pinecone/v4/pinecone"
)

func Namespaces() {
	ctx := context.Background()

	pc, err := pinecone.NewClient(pinecone.NewClientParams{
		ApiKey: "YOUR_API_KEY",
	})
	if err != nil {
		log.Fatalf("Failed to create Client: %v", err)
	}

	idx, err := pc.DescribeIndex(ctx, "example-index")
	if err != nil {
		log.Fatalf("Failed to describe index \"%v\": %v", idx.Name, err)
	}

	idxConnection, err := pc.Index(pinecone.NewIndexConnParams{Host: idx.Host})
	if err != nil {
		log.Fatalf("Failed to create IndexConnection for Host: %v: %v", idx.Host, err)
	}

	// list namespaces
	limit := uint32(10)
	namespaces, err := idxConnection.ListNamespaces(ctx, &pinecone.ListNamespacesParams{
		Limit: &limit,
	})
	if err != nil {
		log.Fatalf("Failed to list namespaces for Host: %v: %v", idx.Host, err)
	}

	// describe a namespace
	namespace1, err := idxConnection.DescribeNamespace(ctx, namespaces.Namespaces[0].Name)
	if err != nil {
		log.Fatalf("Failed to describe namespace: %v: %v", namespaces.Namespaces[0].Name, err)
	}

	// delete a namespace
	err = idxConnection.DeleteNamespace(namespace1.Name)
	if err != nil {
		log.Fatalf("Failed to delete namespace: %v: %v", "my-namespace-1", err)
	}

	// target a new specific namespace
	idxConnectionNs2 := idxConnection.WithNamespace(namespaces.Namespaces[1].Name)
}

Backups and Restore Jobs

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.

import (
	"context"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/pinecone-io/go-pinecone/v4/pinecone"
)

func BackupsAndRestore() {
	ctx := context.Background()

	clientParams := pinecone.NewClientParams{
		ApiKey: os.Getenv("PINECONE_API_KEY"),
	}

	pc, err := pinecone.NewClient(clientParams)
	if err != nil {
		log.Fatalf("Failed to create Client: %w", err)
	}

	indexName := "my-index"
	backupName := fmt.Sprintf("backup-%s")
	backupDesc := fmt.Sprintf("Backup created for index %s", indexName)
	fmt.Printf("Creating backup: %s for index: %s\n", backupName, indexName)

	backup, err := pc.CreateBackup(ctx, &pinecone.CreateBackupParams{
		IndexName:   indexName,
		Name:        &backupName,
		Description: &backupDesc,
	})
	if err != nil {
		log.Fatalf("Failed to create backup: %w", err)
	}

	backup, err = pc.DescribeBackup(ctx, backup.BackupId)
	if err != nil {
		log.Fatalf("Failed to describe backup: %w", err)
	}

	// wait for backup to be "Complete" before triggering a restore job
	log.Printf("Backup status: %v", backup.Status)

	limit := 10
	backups, err := pc.ListBackups(ctx, &pinecone.ListBackupsParams{
		Limit:     &limit,
		IndexName: &indexName,
	})
	if err != nil {
		log.Fatalf("Failed to list backups: %w", err)
	}

	// create a new serverless index from the backup
	restoredIndexName := indexName + "-from-backup"
	restoredIndexTags := pinecone.IndexTags{"restored_on": time.Now().Format("2006-01-02 15:04")}
	createIndexFromBackupResp, err := pc.CreateIndexFromBackup(context.Background(), &pinecone.CreateIndexFromBackupParams{
		BackupId: ts.backupId,
		Name:     restoredIndexName,
		Tags:     &restoredIndexTags,
	})

	// check the status of the index restoration
	restoreJob, err := pc.DescribeRestoreJob(ctx, restoreJob.RestoreJobId)
	if err != nil {
		log.Fatalf("Failed to describe restore job: %w", err)
	}
}

Inference Models

You can now use the InferenceService class within Client.Inference to browse models hosted by Pinecone, including detailed configuration options for each model.

You can list all available models, with the options of filtering by model Type ("embed", "rerank"), and VectorType ("sparse", "dense") for models with Type "embed".

import (
	"context"
	"log"

	"github.com/pinecone-io/go-pinecone/v4/pinecone"
)

func InferenceModels() {
	ctx := context.Background()

	pc, err := pinecone.NewClient(pinecone.NewClientParams{
		ApiKey: "YOUR_API_KEY",
	})
	if err != nil {
		log.Fatalf("Failed to create Client: %v", err)
	}

	embed := "embed"
	rerank := "rerank"

	embedModels, err := pc.Inference.ListModels(ctx, &pinecone.ListModelsParams{
		Type: &embed,
	})
	if err != nil {
		log.Fatalf("Failed to list embedding models: %v", err)
	}

	rerankModels, err := pc.Inference.ListModels(ctx, &pinecone.ListModelsParams{
		Type: &rerank,
	})
	if err != nil {
		log.Fatalf("Failed to list reranking models: %v", err)
	}
}

You can also describe a single model by name:

import (
	"context"
	"fmt"
	"log"

	"github.com/pinecone-io/go-pinecone/v4/pinecone"
)

func InferenceModel() {
	ctx := context.Background()

	pc, err := pinecone.NewClient(pinecone.NewClientParams{
		ApiKey: "YOUR_API_KEY",
	})
	if err != nil {
		log.Fatalf("Failed to create Client: %v", err)
	}

	model, err := pc.Inference.DescribeModel(ctx, "multilingual-e5-large")
	if err != nil {
		log.Fatalf("Failed to get model: %v", err)
	}

	fmt.Printf("Model (multilingual-e5-large): %+v\n", model)
}

Bug fixes & Breaking Changes

IndexConnection now properly supports targeting multiple namespaces in an index while reusing the underlying gRPC connection instead of needing to re-dial every time. you want to target a new namespace in your index. IndexConnection used to expose Namespace as a field, which could be updated at any time, and was originally set when creating a new IndexConnection through Client using NewIndexConnParams. Now, you can re-use IndexConnection against a new namespace by using IndexConnection.WithNamespace, which will return a new pointer to a shallow copy of the struct.

package main

import (
	"context"
	"log"

	"github.com/pinecone-io/go-pinecone/v4/pinecone"
)

func WithNamespace() {
	ctx := context.Background()

	pc, err := pinecone.NewClient(pinecone.NewClientParams{
		ApiKey: "YOUR_API_KEY",
	})
	if err != nil {
		log.Fatalf("Failed to create Client: %v", err)
	}

	idx, err := pc.DescribeIndex(ctx, "example-index")
	if err != nil {
		log.Fatalf("Failed to describe index \"%v\": %v", idx.Name, err)
	}

	idxConnectionNs1, err := pc.Index(pinecone.NewIndexConnParams{Host: idx.Host, Namespace: "namespace-1"})
	if err != nil {
		log.Fatalf("Failed to create IndexConnection for Host: %v: %v", idx.Host, err)
	}

	// This will reuse the gRPC connection while targeting a different namespace
	idxConnectionNs2 := idxConnectionNs1.WithNamespace("namespace-2")

	vectors := []*pinecone.Vector{
		{
			Id:     "A",
			Values: []float32{0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1},
		},
		{
			Id:     "B",
			Values: []float32{0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2},
		},
		{
			Id:     "C",
			Values: []float32{0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3},
		},
		{
			Id:     "D",
			Values: []float32{0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4},
		},
	}

	countNs1, err := idxConnectionNs1.UpsertVectors(ctx, vectors)
	if err != nil {
		log.Fatalf("Failed to upsert vectors to \"example-index\" in \"namespace-1\": %w", err)
	}

	countNs2, err := idxConnectionNs2.UpsertVectors(ctx, vectors)
	if err != nil {
		log.Fatalf("Failed to upsert vectors to \"example-index\" in \"namespace-1\": %w", err)
	}
}

The Embed operation on InferenceService now properly returns different structs when you're embedding using a sparse or dense model. Previously, only dense embedding values would be returned successfully. To handle this, the Embedding type has been updated to a tagged union holding one of either two pointers to a SparseEmbedding, or DenseEmbedding.

What's Changed

New Contributors

Full Changelog: v3.1.0...v4.0.0

Release v3.1.0

20 Mar 07:16
Compare
Choose a tag to compare

Features

Indexes with integrated inference

This release adds a new CreateIndexForModel method to the Client class, and UpsertRecords and SearchRecords to the IndexConnection class. These methods allow you to work with integrated inference, and 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.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/pinecone-io/go-pinecone/v3/pinecone"
)

func otherMain() {
	ctx := context.Background()

	clientParams := pinecone.NewClientParams{
		ApiKey: os.Getenv("PINECONE_API_KEY"),
	}

	pc, err := pinecone.NewClient(clientParams)
	if err != nil {
		log.Fatalf("Failed to create Client: %v", err)
	} else {
		fmt.Println("Successfully created a new Client object!")
	}

	// Create an integrated index
	index, err := pc.CreateIndexForModel(ctx, &pinecone.CreateIndexForModelRequest{
		Name:   "integrated-index",
		Cloud:  "aws",
		Region: "us-east-1",
		Embed: pinecone.CreateIndexForModelEmbed{
			Model:    "multilingual-e5-large",
			FieldMap: map[string]interface{}{"text": "chunk_text"},
		},
	})

	if err != nil {
		log.Fatalf("Failed to create serverless integrated index: %v", err)
	} else {
		fmt.Printf("Successfully created serverless integrated index: %s", index.Name)
	}

	idxConnection, err := pc.Index(pinecone.NewIndexConnParams{Host: index.Host, Namespace: "my-namespace"})
	if err != nil {
		log.Fatalf("Failed to connect to index: %v", err)
	}

	records := []*pinecone.IntegratedRecord{
		{
			"_id":        "rec1",
			"chunk_text": "Apple's first product, the Apple I, was released in 1976 and was hand-built by co-founder Steve Wozniak.",
			"category":   "product",
		},
		{
			"_id":        "rec2",
			"chunk_text": "Apples are a great source of dietary fiber, which supports digestion and helps maintain a healthy gut.",
			"category":   "nutrition",
		},
		{
			"_id":        "rec3",
			"chunk_text": "Apples originated in Central Asia and have been cultivated for thousands of years, with over 7,500 varieties available today.",
			"category":   "cultivation",
		},
		{
			"_id":        "rec4",
			"chunk_text": "In 2001, Apple released the iPod, which transformed the music industry by making portable music widely accessible.",
			"category":   "product",
		},
		{
			"_id":        "rec5",
			"chunk_text": "Apple went public in 1980, making history with one of the largest IPOs at that time.",
			"category":   "milestone",
		},
		{
			"_id":        "rec6",
			"chunk_text": "Rich in vitamin C and other antioxidants, apples contribute to immune health and may reduce the risk of chronic diseases.",
			"category":   "nutrition",
		},
		{
			"_id":        "rec7",
			"chunk_text": "Known for its design-forward products, Apple's branding and market strategy have greatly influenced the technology sector and popularized minimalist design worldwide.",
			"category":   "influence",
		},
		{
			"_id":        "rec8",
			"chunk_text": "The high fiber content in apples can also help regulate blood sugar levels, making them a favorable snack for people with diabetes.",
			"category":   "nutrition",
		},
	}

	// Upsert text records
	err = idxConnection.UpsertRecords(ctx, records)
	if err != nil {
		log.Fatalf("Failed to upsert vectors. Error: %v", err)
	}

	// Search for relevant records and rerank results
	topN := int32(2)
	res, err := idxConnection.SearchRecords(ctx, &pinecone.SearchRecordsRequest{
		Query: pinecone.SearchRecordsQuery{
			TopK: 5,
			Inputs: &map[string]interface{}{
				"text": "Disease prevention",
			},
		},
		Rerank: &pinecone.SearchRecordsRerank{
			Model:      "bge-reranker-v2-m3",
			TopN:       &topN,
			RankFields: []string{"chunk_text"},
		},
		Fields: &[]string{"chunk_text", "category"},
	})
	if err != nil {
		log.Fatalf("Failed to search records: %v", err)
	}
	fmt.Printf("Search results: %+v\n", res)
}

What's Changed

Full Changelog: v3.0.0...v3.1.0

Release v3.0.0

06 Feb 23:12
Compare
Choose a tag to compare

This version of the Pinecone Go SDK depends on version 2025-01 of the Pinecone API. You can read more about versioning here. This v3 SDK release line should continue to receive fixes as long as the 2025-01 API version is in support.

Features

Sparse index support

You can now work with sparse-only indexes. These indexes enable direct indexing and retrieval of sparse vectors, supporting traditional methods like BM25 and learned sparse models such as pinecone-sparse-english-v0. You can read more about getting started with sparse-only indexes here.

The following example demonstrates creating a new sparse-only index, and upserting some arbitrary sparse vector data:

package main

import (
	"context"
	"fmt"
	"github.com/pinecone-io/go-pinecone/v3/pinecone"
	"log"
	"os"
)

func main() {
	ctx := context.Background()

	clientParams := pinecone.NewClientParams{
		ApiKey: os.Getenv("PINECONE_API_KEY"),
	}

	pc, err := pinecone.NewClient(clientParams)
	if err != nil {
		log.Fatalf("Failed to create Client: %v", err)
	} else {
		fmt.Println("Successfully created a new Client object!")
	}

	indexName := "my-serverless-index"
	vectorType := "sparse"
	metric := pinecone.Dotproduct

	idx, err := pc.CreateServerlessIndex(ctx, &pinecone.CreateServerlessIndexRequest{
		Name:       indexName,
		Cloud:      pinecone.Aws,
		Region:     "us-east-1",
		Metric:     &metric,
		VectorType: &vectorType,
		Tags:       &pinecone.IndexTags{"environment": "development"},
	})
	if err != nil {
		log.Fatalf("Failed to create serverless index: %v", err)
	}

	sparseValuesA := pinecone.SparseValues{
		Indices: []uint32{0, 1, 2, 3, 4, 5, 6, 7},
		Values:  []float32{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0},
	}
	sparseValuesB := pinecone.SparseValues{
		Indices: []uint32{0, 1, 2, 3, 4, 5, 6, 7},
		Values:  []float32{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0},
	}
	sparseValuesC := pinecone.SparseValues{
		Indices: []uint32{0, 1, 2, 3, 4, 5, 6, 7},
		Values:  []float32{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0},
	}

	sparseVectors := []*pinecone.Vector{
		{
			Id:           "A",
			Metadata:     metadata,
			SparseValues: &sparseValuesA,
		},
		{
			Id:           "B",
			Metadata:     metadata,
			SparseValues: &sparseValuesB,
		},
		{
			Id:           "C",
			Metadata:     metadata,
			SparseValues: &sparseValuesC,
		},
	}
}

Breaking Changes

  • EmbedParameters is no longer typed as a pointer.
  • CreateServerlessIndexRequest and CreatePodIndexRequest structs have been updated, and fields are now classified as pointers to better denote optionality around creating specific types of indexes: Metric, Dimension, VectorType, and DeletionProtection.
  • Values in the Vector type are now a pointer to allow flexibility when working with sparse-only indexes.

What's Changed

Full Changelog: v2.2.0...v3.0.0

Release v2.2.0

07 Jan 17:01
Compare
Choose a tag to compare

This release includes a fix to the go.mod file which properly updates the module to include "v2": module github.com/pinecone-io/go-pinecone/v2. This allows proper installation and documentation of v2.X.X.

This release also includes features from the previous two releases (v2.0.0, and v2.1.0):

Features

Rerank

The InferenceService has a new operation called Rerank which provides users the ability to rerank documents in descending relevance-order against a given query. Reranking documents is a common "second-pass" ranking strategy broadly used in retrieval applications.

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/pinecone-io/go-pinecone/pinecone"
)

func main() {
    ctx := context.Background()

    pc, err := pinecone.NewClient(pinecone.NewClientParams{
        ApiKey: "YOUR_API_KEY",
    })
    if err != nil {
        log.Fatalf("Failed to create Client: %v", err)
    }

    rerankModel := "bge-reranker-v2-m3"
    topN := 4
    returnDocuments := true
    documents := []pinecone.Document{
        {"id": "vec1", "my_field": "Apple is a popular fruit known for its sweetness and crisp texture."},
        {"id": "vec2", "my_field": "Many people enjoy eating apples as a healthy snack."},
        {"id": "vec3", "my_field": "Apple Inc. has revolutionized the tech industry with its sleek designs and user-friendly interfaces."},
        {"id": "vec4", "my_field": "An apple a day keeps the doctor away, as the saying goes."},
    }

    ranking, err := pc.Inference.Rerank(ctx, &pinecone.RerankRequest{
        Model:           rerankModel,
        Query:           "The tech company Apple is known for its innovative products like the iPhone.",
        ReturnDocuments: &returnDocuments,
        TopN:            &topN,
        RankFields:      &[]string{"my_field"},
        Documents:       documents,
    })
    if err != nil {
        log.Fatalf("Failed to rerank: %v", err)
    }
    fmt.Printf("Rerank result: %+v\n", ranking)
}

Import

IndexConnection now exposes additional methods for working with Import operations. An Import is a long-running, asynchronous operation that gives users the ability to import vectors directly from object storage (e.g. S3) into a Pinecone index. It is intended to be used with large-scale jobs. For small-scale jobs (e.g. <1000 vectors), we recommend continuing to use upsert.

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/pinecone-io/go-pinecone/pinecone"
)

func main() {
    ctx := context.Background()

    pc, err := pinecone.NewClient(pinecone.NewClientParams{
        ApiKey: "YOUR_API_KEY",
    })
    if err != nil {
        log.Fatalf("Failed to create Client: %v", err)
    }

    idx, err := pc.DescribeIndex(ctx, "example-name")
    if err != nil {
        log.Fatalf("Failed to describe index \"%s\". Error:%s", idx.Name, err)
    }

    idxConnection, err := pc.Index(pinecone.NewIndexConnParams{Host: idx.Host})
    if err != nil {
        log.Fatalf("Failed to create IndexConnection for Host: %v. Error: %v", idx.Host, err)
    }

    uri := "s3://BUCKET_NAME/PATH/TO/DIR"
    
    // Start an import
    errorMode := "continue" // or "abort"
    importRes, err := idxConnection.StartImport(ctx, uri, nil, (*pinecone.ImportErrorMode)(&errorMode))
    if err != nil {
        log.Fatalf("Failed to start import: %v", err)
    }
    fmt.Printf("Import started with ID: %s", importRes.Id)

    // Describe an import
    importDesc, err := idxConnection.DescribeImport(ctx, importRes.Id)
    if err != nil {
        log.Fatalf("Failed to describe import: %s - %v", importRes.Id, err)
    }
    fmt.Printf("Import ID: %s, Status: %s", importDesc.Id, importDesc.Status)

    // List imports
    limit := int32(10)
    firstImportPage, err := idxConnection.ListImports(ctx, &limit, nil)
    if err != nil {
        log.Fatalf("Failed to list imports: %v", err)
    }
    fmt.Printf("First page of imports: %+v", firstImportPage.Imports)

    paginationToken := firstImportPage.NextPaginationToken
    nextImportPage, err := idxConnection.ListImports(ctx, &limit, paginationToken)
    if err != nil {
        log.Fatalf("Failed to list imports: %v", err)
    }
    fmt.Printf("Second page of imports: %+v", nextImportPage.Imports)

    // Cancel import
    err = idxConnection.CancelImport(ctx, importRes.Id)
    if err != nil {
        log.Fatalf("Failed to cancel import: %s", importRes.Id)
    }
}

Index Tags

You can now assign index tags when creating or configuring indexes. Tags are key-value pairs that you can use to categorize and identify the index.

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/pinecone-io/go-pinecone/pinecone"
)

func main() {
    ctx := context.Background()

    pc, err := pinecone.NewClient(pinecone.NewClientParams{
        ApiKey: "YOUR_API_KEY",
    })

    if err != nil {
        log.Fatalf("Failed to create Client: %v", err)
    }

    // Create an index with Tags
    idx, err := pc.CreateServerlessIndex(ctx, &pinecone.CreateServerlessIndexRequest{
        Name:      "my-tagged-index",
        Dimension: 3,
        Metric:    pinecone.Cosine,
        Cloud:     pinecone.Aws,
        Region:    "us-east-1",
        Tags:       &pinecone.IndexTags{ "environment": "development" },
    })

    if err != nil {
        log.Fatalf("Failed to create index: %v", err)
    }

    // Update an index's Tags with ConfigureIndex
    idx, err = pc.ConfigureIndex(context.Background(),
		ts.idxName,
		pinecone.ConfigureIndexParams{Tags: IndexTags{"environment": "production"}})
    
    if err != nil {
        log.Fatalf("Failed to configure index: %v", err)
    }
}

What's Changed

Full Changelog: v2.1.0...v2.2.0

Release v2.1.0

21 Dec 07:06
Compare
Choose a tag to compare

Features

Index Tags

You can now assign index tags when creating or configuring indexes. Tags are key-value pairs that you can use to categorize and identify the index.

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/pinecone-io/go-pinecone/pinecone"
)

func main() {
    ctx := context.Background()

    pc, err := pinecone.NewClient(pinecone.NewClientParams{
        ApiKey: "YOUR_API_KEY",
    })

    if err != nil {
        log.Fatalf("Failed to create Client: %v", err)
    }

    // Create an index with Tags
    idx, err := pc.CreateServerlessIndex(ctx, &pinecone.CreateServerlessIndexRequest{
        Name:      "my-tagged-index",
        Dimension: 3,
        Metric:    pinecone.Cosine,
        Cloud:     pinecone.Aws,
        Region:    "us-east-1",
        Tags:       &pinecone.IndexTags{ "environment": "development" },
    })

    if err != nil {
        log.Fatalf("Failed to create index: %v", err)
    }

    // Update an index's Tags with ConfigureIndex
    idx, err = pc.ConfigureIndex(context.Background(),
		ts.idxName,
		pinecone.ConfigureIndexParams{Tags: IndexTags{"environment": "production"}})
    
    if err != nil {
        log.Fatalf("Failed to configure index: %v", err)
    }
}

What's Changed

Full Changelog: v2.0.0...v2.1.0

Release v2.0.0

23 Oct 22:34
Compare
Choose a tag to compare

This version of the Pinecone Go SDK supports version 2024-10 of the Pinecone API. You can read more about versioning here.

Features

Rerank

The InferenceService has a new operation called Rerank which provides users the ability to rerank documents in descending relevance-order against a given query. Reranking documents is a common "second-pass" ranking strategy broadly used in retrieval applications.

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/pinecone-io/go-pinecone/pinecone"
)

func main() {
    ctx := context.Background()

    pc, err := pinecone.NewClient(pinecone.NewClientParams{
        ApiKey: "YOUR_API_KEY",
    })
    if err != nil {
        log.Fatalf("Failed to create Client: %v", err)
    }

    rerankModel := "bge-reranker-v2-m3"
    topN := 4
    returnDocuments := true
    documents := []pinecone.Document{
        {"id": "vec1", "my_field": "Apple is a popular fruit known for its sweetness and crisp texture."},
        {"id": "vec2", "my_field": "Many people enjoy eating apples as a healthy snack."},
        {"id": "vec3", "my_field": "Apple Inc. has revolutionized the tech industry with its sleek designs and user-friendly interfaces."},
        {"id": "vec4", "my_field": "An apple a day keeps the doctor away, as the saying goes."},
    }

    ranking, err := pc.Inference.Rerank(ctx, &pinecone.RerankRequest{
        Model:           rerankModel,
        Query:           "The tech company Apple is known for its innovative products like the iPhone.",
        ReturnDocuments: &returnDocuments,
        TopN:            &topN,
        RankFields:      &[]string{"my_field"},
        Documents:       documents,
    })
    if err != nil {
        log.Fatalf("Failed to rerank: %v", err)
    }
    fmt.Printf("Rerank result: %+v\n", ranking)
}

Import

IndexConnection now exposes additional methods for working with Import operations. An Import is a long-running, asynchronous operation that gives users the ability to import vectors directly from object storage (e.g. S3) into a Pinecone index. It is intended to be used with large-scale jobs. For small-scale jobs (e.g. <1000 vectors), we recommend continuing to use upsert.

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/pinecone-io/go-pinecone/pinecone"
)

func main() {
    ctx := context.Background()

    pc, err := pinecone.NewClient(pinecone.NewClientParams{
        ApiKey: "YOUR_API_KEY",
    })
    if err != nil {
        log.Fatalf("Failed to create Client: %v", err)
    }

    idx, err := pc.DescribeIndex(ctx, "example-name")
    if err != nil {
        log.Fatalf("Failed to describe index \"%s\". Error:%s", idx.Name, err)
    }

    idxConnection, err := pc.Index(pinecone.NewIndexConnParams{Host: idx.Host})
    if err != nil {
        log.Fatalf("Failed to create IndexConnection for Host: %v. Error: %v", idx.Host, err)
    }

    uri := "s3://BUCKET_NAME/PATH/TO/DIR"
    
    // Start an import
    errorMode := "continue" // or "abort"
    importRes, err := idxConnection.StartImport(ctx, uri, nil, (*pinecone.ImportErrorMode)(&errorMode))
    if err != nil {
        log.Fatalf("Failed to start import: %v", err)
    }
    fmt.Printf("Import started with ID: %s", importRes.Id)

    // Describe an import
    importDesc, err := idxConnection.DescribeImport(ctx, importRes.Id)
    if err != nil {
        log.Fatalf("Failed to describe import: %s - %v", importRes.Id, err)
    }
    fmt.Printf("Import ID: %s, Status: %s", importDesc.Id, importDesc.Status)

    // List imports
    limit := int32(10)
    firstImportPage, err := idxConnection.ListImports(ctx, &limit, nil)
    if err != nil {
        log.Fatalf("Failed to list imports: %v", err)
    }
    fmt.Printf("First page of imports: %+v", firstImportPage.Imports)

    paginationToken := firstImportPage.NextPaginationToken
    nextImportPage, err := idxConnection.ListImports(ctx, &limit, paginationToken)
    if err != nil {
        log.Fatalf("Failed to list imports: %v", err)
    }
    fmt.Printf("Second page of imports: %+v", nextImportPage.Imports)

    // Cancel import
    err = idxConnection.CancelImport(ctx, importRes.Id)
    if err != nil {
        log.Fatalf("Failed to cancel import: %s", importRes.Id)
    }
}

Changes Overview

New Contributors

Full Changelog: v1.1.1...v2.0.0

Release v1.1.1

18 Sep 16:55
Compare
Choose a tag to compare

Fixes

Chores

  • [Docs] Return error for serverless index creation failure by @jseldess in #71
  • [Chore] Refactor sparse vector integration tests by @austin-denoble in #72

Full Changelog: v1.1.0...v1.1.1

Release v1.1.0

23 Aug 22:12
Compare
Choose a tag to compare

Features

Inference API

You can now try out Pinecone's Inference API, which is currently in public preview. See the README for more details.

ctx := context.Background()

pc, err := pinecone.NewClient(pinecone.NewClientParams{
   ApiKey: "YOUR_API_KEY",
})
if err !=  nil {
   log.Fatalf("Failed to create Client: %v", err)
}

embeddingModel := "multilingual-e5-large"
documents := []string{
   "Turkey is a classic meat to eat at American Thanksgiving."
   "Many people enjoy the beautiful mosques in Turkey."
}
docParameters := pinecone.EmbedParameters{
   InputType: "passage",
   Truncate: "END",
}

docEmbeddingsResponse, err := pc.Inference.Embed(ctx, &pinecone.EmbedRequest{
   Model: embeddingModel,
   TextInputs: documents,
   Parameters: docParameters,
})
if err != nil {
   log.Fatalf("Failed to embed documents: %v", err)
}
fmt.Printf("docs embedding response: %+v", docEmbeddingsResponse)

// << Upsert documents into Pinecone >>

Changes overview

New Contributors

Full Changelog: v1.0.0...v1.1.0

Release v1.0.0

06 Aug 15:57
1abbeab
Compare
Choose a tag to compare

Features

API Versioning

This first major release of the Pinecone Go SDK depends on API version 2024-07. This v1 SDK release line will continue to receive fixes as long as the 2024-07 API version is in support. Learn more about Pinecone API versioning here.

Configure Index

You can now configure an index using client.ConfigureIndex with the pinecone.ConfigureIndexParams struct. This can be used to adjust the Replicas or PodType of a pods-based index, or enabling or disabling deletion protection for all index types.

package main

import (
	"context"
	"github.com/pinecone-io/go-pinecone/pinecone"
	"log"
	"os"
)

func main() {
    ctx := context.Background()

    clientParams := pinecone.NewClientParams{
        ApiKey: os.Getenv("PINECONE_API_KEY"),
    }

    pc, err := pinecone.NewClient(clientParams)
    if err != nil {
        log.Fatalf("Failed to create Client: %v", err)
    } 

    // To scale the size of your pods-based index from "x2" to "x4":
    _, err := pc.ConfigureIndex(ctx, "my-pod-index", pinecone.ConfigureIndexParams{PodType: "p1.x4"})
    if err != nil {
	log.Fatalf("Failed to configure index: %v\n", err)
    }

    // To scale the number of replicas to 4:
    _, err := pc.ConfigureIndex(ctx, "my-pod-index", pinecone.ConfigureIndexParams{Replicas: 4})
    if err != nil {
	log.Fatalf("Failed to configure index: %v\n", err)
    }

Deletion Protection

Use deletion protection to prevent your most important indexes from accidentally being deleted. This feature is available for both serverless and pod indexes.

package main

import (
	"context"
	"github.com/pinecone-io/go-pinecone/pinecone"
	"log"
	"os"
)

func main() {
    ctx := context.Background()

    clientParams := pinecone.NewClientParams{
        ApiKey: os.Getenv("PINECONE_API_KEY"),
    }

    pc, err := pinecone.NewClient(clientParams)
    if err != nil {
        log.Fatalf("Failed to create Client: %v", err)
    }

    // create a new index with deletion protection enabled
    idx, err := pc.CreateServerlessIndex(ctx, &pinecone.CreateServerlessIndexRequest{
        Name:      "my-protected-index",
        Dimension: 3,
        Metric:    pinecone.Cosine,
        Cloud:     pinecone.Aws,
        Region:    "us-east-1",
        DeletionProtection: "enabled",
    })
    if err != nil {
        log.Fatalf("Failed to create index: %v\n", err)
    }

    // To enable deletion protection for an existing index
    _, err := pc.ConfigureIndex(ctx, "my-index", pinecone.ConfigureIndexParams{DeletionProtection: "enabled"})
    if err != nil {
        log.Fatalf("Failed to configure index: %v\n", err)
    }
}

For users of the unstable pre-v1.0.0 SDK: see the README for details on which operations and types have changed. At a high level:

  • pinecone.NewClient accepts additional configuration options through pinecone.NewClientParams.
  • Creating an IndexConnection when working with the data plane has been simplified to a single client.Index method which takes in a pinecone.NewIndexConnParams struct to configure the connection.
  • When working with an IndexConnection, types such as FetchVectorsResponse and QueryVectorsResponse will now contain the Namespace of the source index.

Changes Overview

New Contributors

Full Changelog: v0.5.0...v1.0.0