Mythosia.VectorDb.Pinecone
2.0.0
See the version list below for details.
dotnet add package Mythosia.VectorDb.Pinecone --version 2.0.0
NuGet\Install-Package Mythosia.VectorDb.Pinecone -Version 2.0.0
<PackageReference Include="Mythosia.VectorDb.Pinecone" Version="2.0.0" />
<PackageVersion Include="Mythosia.VectorDb.Pinecone" Version="2.0.0" />
<PackageReference Include="Mythosia.VectorDb.Pinecone" />
paket add Mythosia.VectorDb.Pinecone --version 2.0.0
#r "nuget: Mythosia.VectorDb.Pinecone, 2.0.0"
#:package Mythosia.VectorDb.Pinecone@2.0.0
#addin nuget:?package=Mythosia.VectorDb.Pinecone&version=2.0.0
#tool nuget:?package=Mythosia.VectorDb.Pinecone&version=2.0.0
Mythosia.VectorDb.Pinecone
Pinecone vector store implementation for the Mythosia VectorDb abstraction layer.
Isolation model used by this package:
- Collection = Pinecone index (physical storage)
- Namespace = Pinecone namespace (1st-tier logical partition)
- Scope = metadata key
_scope(2nd-tier logical partition)
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"
};
using var store = new PineconeStore(options);
var record = new VectorRecord("doc-1", embedding, "Hello world");
await store.InNamespace("documents").UpsertAsync(record);
var results = await store.InNamespace("documents")
.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 |
DefaultNamespace |
null |
Namespace used when record/filter namespace is null |
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.InNamespace("documents")
.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.
Scope & Metadata Filtering
await store.InNamespace("docs").InScope("tenant-1").UpsertAsync(record);
var results = await store.InNamespace("docs").InScope("tenant-1")
.SearchAsync(queryVector, topK: 10);
var filter = new VectorFilter().Where("category", "science");
var filtered = await store.InNamespace("docs")
.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 |
_scope |
Scope for 2nd-tier isolation (omitted if null) |
<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.InNamespace("documents").ReplaceByFilterAsync(filter, newRecords);
Batch Get & Count
// Fetch multiple records by ID — single HTTP call to /vectors/fetch?ids=...
var records = await store.InNamespace("documents").GetBatchAsync(new[] { "id-1", "id-2", "id-3" });
// Count total vectors in a namespace
long count = await store.InNamespace("documents").CountAsync();
// Count with metadata filter (POSTs filter to describe_index_stats)
long filtered = await store.InNamespace("documents").CountAsync(
new VectorFilter().Where("category", "finance"));
GetBatchAsync issues a single GET /vectors/fetch?ids=id1&ids=id2&... request per namespace. 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 (>= 3.0.0)
- 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.
v2.0.0: Requires Abstractions v3.0.0 — VectorFilter.ByMetadata/ByNamespace/ByScope and MetadataMatch are removed. Use new fluent API: new VectorFilter().Where(...). Pinecone metadata filter builder updated for the full condition tree: 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 skipped server-side, evaluated client-side in MatchesFilter.