Pinecone.net هي مكتبة C# ممتلئة بالكامل لقاعدة بيانات Pinecone Vector.
هذه مكتبة مجتمعية توفر دعمًا من الدرجة الأولى لـ Pinecone في C# و F#.
dotnet add package Pinecone.NET أو Install-Package Pinecone.NET
العمل مع الفهارس
using Pinecone ;
// Initialize the client with your API key
using var pinecone = new PineconeClient ( "your-api-key" ) ;
// List all indexes
var indexes = await pinecone . ListIndexes ( ) ;
// Create a new index if it doesn't exist
var indexName = "myIndex" ;
if ( ! indexes . Contains ( indexName ) )
{
await pinecone . CreateServerlessIndex ( indexName , 1536 , Metric . Cosine , "aws" , "us-east-1" ) ;
}
// Get the Pinecone index by name (uses REST by default).
// The index client is thread-safe, consider caching and/or
// injecting it as a singleton into your DI container.
using var index = await pinecone . GetIndex ( indexName ) ;
// Configure an index
await pinecone . ConfigureIndex ( indexName , replicas : 2 , podType : "p2" ) ;
// Delete an index
await pinecone . DeleteIndex ( indexName ) ;العمل مع المتجهات
// Assuming you have an instance of `index`
// Create and upsert vectors
var vectors = new [ ]
{
new Vector
{
Id = "vector1" ,
Values = new float [ ] { 0.1f , 0.2f , 0.3f , .. . } ,
Metadata = new MetadataMap
{
[ "genre" ] = "horror" ,
[ "duration" ] = 120
}
}
} ;
await index . Upsert ( vectors ) ;
// Fetch vectors by IDs
var fetched = await index . Fetch ( [ "vector1" ] ) ;
// Query scored vectors by ID
var scored = await index . Query ( "vector1" , topK : 10 ) ;
// Query scored vectors by a new, previously unseen vector
var vector = new [ ] { 0.1f , 0.2f , 0.3f , .. . } ;
var scored = await index . Query ( vector , topK : 10 ) ;
// Query scored vectors by ID with metadata filter
var filter = new MetadataMap
{
[ "genre" ] = new MetadataMap
{
[ "$in" ] = new [ ] { "documentary" , "action" }
}
} ;
var scored = await index . Query ( "birds" , topK : 10 , filter ) ;
// Delete vectors by vector IDs
await index . Delete ( new [ ] { "vector1" } ) ;
// Delete vectors by metadata filter
await index . Delete ( new MetadataMap
{
[ "genre" ] = new MetadataMap
{
[ "$in" ] = new [ ] { "documentary" , "action" }
}
} ) ;
// Delete all vectors in the index
await index . DeleteAll ( ) ;العمل مع المجموعات
using Pinecone ;
// Assuming you have an instance of `PineconeClient` named `pinecone`
// List all collections
var collections = await pinecone . ListCollections ( ) ;
// Create a new collection
await pinecone . CreateCollection ( "myCollection" , "myIndex" ) ;
// Describe a collection
var details = await pinecone . DescribeCollection ( "myCollection" ) ;
// Delete a collection
await pinecone . DeleteCollection ( "myCollection" ) ; التعافي من الفشل على انتفاضة متوازية مكثفة
// Upsert with recovery from up to three failures on batched parallel upsert.
//
// The parallelization is done automatically by the client based on the vector
// dimension and the number of vectors to upsert. It aims to keep the individual
// request size below Pinecone's 2MiB limit with some safety margin for metadata.
// This behavior can be further controlled by calling the 'Upsert' overload with
// custom values for 'batchSize' and 'parallelism' parameters.
//
// This is not the most efficient implementation in terms of allocations in
// GC pause frequency sensitive scenarios, but is perfectly acceptable
// for pretty much all regular back-end applications.
// Assuming there is an instance of 'index' available
// Generate 25k random vectors
var vectors = Enumerable
. Range ( 0 , 25_000 )
. Select ( _ => new Vector
{
Id = Guid . NewGuid ( ) . ToString ( ) ,
Values = Enumerable
. Range ( 0 , 1536 )
. Select ( _ => Random . Shared . NextSingle ( ) )
. ToArray ( )
} )
. ToArray ( ) ;
// Specify the retry limit we are okay with
var retries = 3 ;
while ( true )
{
try
{
// Perform the upsert
await index . Upsert ( vectors ) ;
// If no exception is thrown, break out of the retry loop
break ;
}
catch ( ParallelUpsertException e ) when ( retries -- > 0 )
{
// Create a hash set to efficiently filter out the failed vectors
var filter = e . FailedBatchVectorIds . ToHashSet ( ) ;
// Filter out the failed vectors from the batch and assign them to
// the 'vectors' variable consumed by 'Upsert' operation above
vectors = vectors . Where ( v => filter . Contains ( v . Id ) ) . ToArray ( ) ;
Console . WriteLine ( $ "Retrying upsert due to error: { e . Message } " ) ;
}
} يمكن استخدام نهج مماثل للتعافي من العمليات الأخرى المتدفقة أو المدمجة.
انظر ListOperationException ، ParallelFetchException و ParallelDeleteException في vectortypes.cs.
تفضل RestTransport افتراضيًا. يرجى العثور على التفسير التفصيلي لسيناريوهات محددة أدناه.
GrpcTransport هو بديل قابل للتطبيق لتقليل حركة مرور الشبكة عند العمل مع ناقلات كبيرة تحت سيناريوهات إنتاجية منخفضة إلى معتدلة.
يقوم ProtoBuf بتشفير المتجهات بطريقة أكثر إحكاما ، لذلك إذا كان لديك متجهات عالية الأبعاد (1536-3072+) ، درجة منخفضة من التزامن الطلب وعادة ما تنقص أو جلب المتجهات في Bacthes الصغيرة ، فهذا يستحق النظر في GrpcTransport لحالة الاستخدام الخاصة بك.
Delete الناحية النظرية ، قد تكون إنتاجية التزامن المنخفضة أعلى مع GrpcTransport بسبب انخفاض حركة الشبكة ، ولكن نظرًا لأن مدى تافهة إرسال طلبات متعددة بالتوازي (وحقيقة أن Fetch Upsert القيام بذلك تلقائيًا) ، فمن المحتمل أن تكون مزايا هذا النهج محدودة.
في وقت كتابة هذا التقرير ، تم تكوين مكدس HTTP/2 من Pinecone للسماح ببعض أو حتى دفق متزامن واحد لكل اتصال HTTP/2 واحد.
نظرًا لأن HTTP/2 إلزامي لـ GRPC ، فإن هذا يتسبب في طابور طلب كبير على قناة GRPC في ظل سيناريوهات التزامن العالية ، مما يؤدي إلى سوء التوسع في GrpcTransport مع انخفاض سقف الإنتاجية.
قد يواجه المستخدمون الذين ليسوا على دراية بهذا القيد زيادة غير متوقعة في عمليات الاستعلام الخاصة بهم تحت عدد المستخدمين المتناميين لكل عقدة التطبيق و/أو أقل بكثير من الارتفاع الجاهز وجلب الإنتاجية حتى عند تحديد درجة أكبر من التوازي لعمليات Upsert Fetch يدويًا.
Pinecone.NET يخفف جزئيًا من هذه المشكلة من خلال تكوين قناة GRPC للاستفادة من موازنة التحميل من جانب العميل (سجلات DNS) للاستفادة من القنوات الفرعية المتعددة (يوجد حاليًا 3 كما تم إرجاعها بواسطة استعلام DNS) ، والتي من المتوقع أن توفر إنتاجية أفضل من العملاء الآخرين. كما أنه يتيح استخدام اتصالات HTTP/2 المتعددة لكل نقطة نهاية SocketsHttpHandler الأساسي ، لكن يبدو أن تطبيق GRPC الحالي لا يستفيد من هذا بشكل صحيح.
ما سبق هو ملاحظة لسلوك العميل تحت اختبار التحميل وقد تكون عوامل البنية التحتية الإضافية في اللعب كما هو موضح من قبل تقارير المستخدم في قابلية التوسع في منتدى Community Community في تطبيقات أخرى.
قد يرغب المستخدمون الخبراء الذين ما زالوا يرغبون في استخدام نقل GRPC في سيناريوهات التحميل العالي إلى استكشاف المزيد من عناصر الإجراءات التي هي خارج نطاق هذه المكتبة البسيطة المدعومة من المجتمع:
يُنصح المستخدمون العاديون باستخدام RestTransport لسيناريوهات التزامن عالية الإنتاجية و/أو العالية بدلاً من ذلك ، ما لم يكن تقييمهم لـ GrpcTransport في بيئتهم المحددة ينتج عنه نتائج أفضل.
اعتبارًا من الآن ، يبدو أن RestTransport و System.Text.Json يستخدم للتسلسل أكثر فعالية من الذاكرة من GrpcTransport و Protobuf . هذا ليس قيودًا متأصلة في GRPC ، بل نتيجة للتنفيذ الحالي لـ grpc-dotnet . تم تحسين System.Text.Json بشكل كبير فيما يتعلق بحركة المرور وتخصيص استخدام ذاكرة مستدامة بشكل كبير تحت كل من الضوء والثقيل. بالنظر إلى الحالة الحالية لتنفيذ grpc-dotnet ، لا أتوقع أن يتغير هذا في المستقبل القريب. إنه "جيد بما يكفي" بالنسبة لمعظم التطبيقات ، ولكن الفرق المستمر في حجم الكومة تحت الحمل مهم بما يكفي لضمان ذكر هذا بشكل صريح.
يرجى ملاحظة أن Pinecone.NET يقوم بالفعل ببناء/قراءة صفرية من RepeatedField<float> التي تخزن قيم المتجهات لتخفيف ضغط التخصيص ، ولكن لا يكفي تعويض ميزة استخدام System.Text.Json .
المساهمات مرحب بها! لا تتردد في فتح مشكلة أو علاقات عامة.