Mythosia.VectorDb.Pinecone
4.0.0
dotnet add package Mythosia.VectorDb.Pinecone --version 4.0.0
NuGet\Install-Package Mythosia.VectorDb.Pinecone -Version 4.0.0
<PackageReference Include="Mythosia.VectorDb.Pinecone" Version="4.0.0" />
<PackageVersion Include="Mythosia.VectorDb.Pinecone" Version="4.0.0" />
<PackageReference Include="Mythosia.VectorDb.Pinecone" />
paket add Mythosia.VectorDb.Pinecone --version 4.0.0
#r "nuget: Mythosia.VectorDb.Pinecone, 4.0.0"
#:package Mythosia.VectorDb.Pinecone@4.0.0
#addin nuget:?package=Mythosia.VectorDb.Pinecone&version=4.0.0
#tool nuget:?package=Mythosia.VectorDb.Pinecone&version=4.0.0
Mythosia.VectorDb.Pinecone
Pinecone vector store implementation for the Mythosia VectorDb abstraction layer.
Isolation model:
- Collection = Pinecone index (physical storage)
- Namespace = Pinecone namespace (optional, via
PineconeOptions.Namespace) - Metadata = all user-defined key-value pairs stored as Pinecone metadata fields
Installation
dotnet add package Mythosia.VectorDb.Pinecone
Quick Start
using Mythosia.VectorDb;
using Mythosia.VectorDb.Pinecone;
var options = new PineconeOptions
{
IndexHost = "https://my-index-xxxx.svc.us-east1-gcp.pinecone.io",
ApiKey = "YOUR_PINECONE_API_KEY",
Namespace = "documents" // optional — scopes all operations to this namespace
};
using var store = new PineconeStore(options);
var record = new VectorRecord("doc-1", embedding, "Hello world");
await store.UpsertAsync(record);
var results = await store.SearchAsync(queryVector, topK: 5);
PineconeStore follows the same hybrid-capable storage model as QdrantStore:
- upserts always store dense vectors and sparse BM25-derived values together
- retrieval mode is chosen at query time
SearchAsyncfor vector-only retrievalHybridSearchAsyncfor native dense + sparse retrieval
For native hybrid search, the Pinecone index metric must be dotproduct.
Options
| Property | Default | Description |
|---|---|---|
IndexHost |
(required) | Pinecone data-plane host for your index |
ApiKey |
(required) | Pinecone API key |
Namespace |
null |
Optional Pinecone namespace. When set, all operations are scoped to this namespace |
UpsertBatchSize |
100 |
Max vectors per upsert request |
RequestTimeoutSeconds |
100 |
Timeout when store owns HttpClient |
AutoCreateIndex |
false |
Auto-create the index through the Pinecone Control Plane API |
IndexName |
null |
Required when AutoCreateIndex = true |
Dimension |
0 |
Required when AutoCreateIndex = true |
Cloud |
null |
Required when AutoCreateIndex = true |
Region |
null |
Required when AutoCreateIndex = true |
ControlPlaneHost |
https://api.pinecone.io |
Pinecone Control Plane API base URL |
When AutoCreateIndex = true, the index is created with dotproduct metric automatically.
AutoCreateIndex example
var options = new PineconeOptions
{
ApiKey = "YOUR_PINECONE_API_KEY",
AutoCreateIndex = true,
IndexName = "my-index",
Dimension = 1536,
Cloud = "aws",
Region = "us-east-1"
// IndexHost is resolved automatically after the index becomes ready
};
using var store = new PineconeStore(options);
// On first use the store creates the index (dotproduct metric) and polls up to
// 2 minutes (60 × 2 s) for it to become ready before accepting requests.
Hybrid Search
var hybridResults = await store.HybridSearchAsync(queryVector, "hello world", topK: 5);
SearchAsync remains pure dense retrieval. HybridSearchAsync sends both dense and sparse query components and lets Pinecone perform server-side fusion.
Metadata Filtering
// Store with metadata for logical isolation
await store.UpsertAsync(new VectorRecord
{
Id = "doc-1",
Content = "Some text",
Vector = embedding,
Metadata = { ["tenant"] = "tenant-1", ["category"] = "science" }
});
// Filter by metadata conditions
var filter = new VectorFilter()
.Where("tenant", "tenant-1")
.Where("category", "science");
var results = await store.SearchAsync(queryVector, topK: 5, filter: filter);
Supported filter operators
| Operator | Pinecone translation |
|---|---|
Eq |
$eq |
Ne |
$ne |
Gt / Gte / Lt / Lte |
$gt / $gte / $lt / $lte |
In |
$in |
NotIn |
$nin |
And / Or groups |
$and / $or |
Like / Exists / NotExists |
Silently ignored for SearchAsync / HybridSearchAsync (no client-side fallback). Evaluated client-side via MatchesFilter for GetAsync / GetBatchAsync only. |
Important: Unsupported operators produce no error but filter nothing in search queries. Use
GetAsync/GetBatchAsyncwhen these operators are required.
VectorFilter
For the full operator reference and fluent API examples (Where, WhereNot, WhereIn, WhereLike, WhereExists, Or, And, WithMinScore, etc.), see the Mythosia.VectorDb.Abstractions README.
Pinecone-specific note:
Like,Exists, andNotExistsare silently ignored inSearchAsync/HybridSearchAsync. They are only evaluated client-side inGetAsync/GetBatchAsync.
Metadata Layout
Each stored vector uses reserved metadata keys:
| Key | Description |
|---|---|
_content |
Original text content |
<custom> |
User metadata entries from VectorRecord.Metadata |
Vector Replacement
ReplaceByFilterAsync is available via the IVectorStore default interface method. It performs sequential DeleteByFilterAsync → UpsertBatchAsync. Pinecone does not support server-side transactions, so sequential execution is the best available behavior:
var filter = new VectorFilter().Where("full_path", "/docs/file.md");
await store.ReplaceByFilterAsync(filter, newRecords);
Batch Get & Count
// Fetch multiple records by ID — single HTTP call to /vectors/fetch?ids=...
var records = await store.GetBatchAsync(new[] { "id-1", "id-2", "id-3" });
// Count total vectors in the configured namespace
long count = await store.CountAsync();
// Count with metadata filter (POSTs filter to describe_index_stats)
long filtered = await store.CountAsync(
new VectorFilter().Where("category", "finance"));
GetBatchAsync issues a single GET /vectors/fetch?ids=id1&ids=id2&... request. CountAsync calls describe_index_stats; when a metadata filter is present, it is sent in a POST body for a server-side filtered count.
Connection Verification
Call VerifyConnectionAsync to test HTTP connectivity to the Pinecone index before running queries:
var store = new PineconeStore(new PineconeOptions
{
IndexHost = "https://my-index-xxxx.svc.us-east1-gcp.pinecone.io",
ApiKey = "YOUR_PINECONE_API_KEY"
});
try
{
await store.VerifyConnectionAsync();
Console.WriteLine("Connected!");
}
catch (Exception ex)
{
Console.WriteLine($"Connection failed: {ex.Message}");
}
Resource Disposal
PineconeStore implements IDisposable. When created via the standard constructor, it owns the internal HttpClient and disposes it on Dispose():
using var store = new PineconeStore(options);
// HttpClient disposed automatically
When injecting a pre-configured HttpClient, the caller retains ownership and is responsible for disposal:
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://my-index-xxxx.svc.us-east1-gcp.pinecone.io");
var store = new PineconeStore(options, httpClient);
// store.Dispose() will NOT dispose httpClient — caller must dispose it separately
API Key Note
Set your Pinecone API key securely (for example, environment variables or secret manager). Do not hardcode secrets in source code.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Mythosia.VectorDb.Abstractions (>= 4.0.1)
- System.IO.Hashing (>= 10.0.5)
- System.Text.Json (>= 10.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
v4.0.0: Breaking — Removed DefaultNamespace and _scope reserved metadata key. Added PineconeOptions.Namespace for explicit namespace scoping. All metadata keys are now treated uniformly.