Skip to content

Pinecone Service

The PineconeService provides integration with the Pinecone vector database for efficient semantic search and retrieval of document embeddings.

Overview

The PineconeService manages connection and interaction with Pinecone, a vector database optimised for similarity search. It provides methods for storing, retrieving, and querying document embeddings, enabling contextually relevant document retrieval for AI-powered features.

Dependencies

The PineconeService depends on:

  • AzureSqlService: For user-specific database operations (with circular dependency handling)
  • Azure Blob Storage: For document storage
  • Pinecone Client: For vector database operations
  • OpenAI Embeddings: For generating document embeddings

Key Methods

getVectorDBID

public async getVectorDBID(userID: string): Promise<string>

Gets or creates a vector database ID for a specific user.

Parameters:

  • userID: The user's unique identifier

Returns:

  • A string representing the user's vector database ID

Functionality:

  1. Checks if the user has an existing vector DB ID in Azure SQL
  2. Creates a new ID if one doesn't exist
  3. Returns the ID for use in Pinecone operations

getVectorStore

public async getVectorStore(userID: string): Promise<PineconeStore>

Retrieves a user-specific PineconeStore instance for document operations.

Parameters:

  • userID: The user's unique identifier

Returns:

  • A PineconeStore instance for the user

Functionality:

  1. Gets the vector database ID for the user
  2. Initializes the Pinecone vector store with appropriate index and namespace
  3. Returns a configured PineconeStore instance for document operations

Example:

const vectorStore = await pineconeService.getVectorStore("user123");
const results = await vectorStore.similaritySearch("bid documentation", 5);

getVectorStoreRetriever

public async getVectorStoreRetriever(userID: string)

Creates a retriever from the user's vector store for use in chains.

Parameters:

  • userID: The user's unique identifier

Returns:

  • A retriever object that can be used in LangChain chains

Functionality:

  1. Gets the vector store for the user
  2. Creates and returns a retriever with configured search parameters

addDocuments

public async addDocuments(userID: string, documents: Document[]): Promise<void>

Adds document embeddings to the user's vector store.

Parameters:

  • userID: The user's unique identifier
  • documents: Array of LangChain Document objects to add

Returns:

  • A Promise that resolves when the documents have been added

Functionality:

  1. Gets the vector store for the user
  2. Creates embeddings for the documents
  3. Adds the documents and their embeddings to the vector store

Implementation Details

Initialization

The service initializes connections to Azure Blob Storage, Pinecone, and OpenAI embeddings:

constructor(
  @Inject(forwardRef(() => AzureSqlService))
  private readonly azureSql: AzureSqlService
) {
  // Initialize connections using environment variables
  this.blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
  this.pineconeClient = new Pinecone({ apiKey: pineconeApiKey });
  this.embeddings = new OpenAIEmbeddings({ openAIApiKey: azureOpenAIApiKey });
}

User-Specific Isolation

The service implements user isolation through namespacing:

  • Each user gets their own namespace within Pinecone
  • Document retrieval is scoped to the user's namespace
  • Database IDs are stored in Azure SQL for persistence

Error Handling

The service implements error handling for:

  • Missing environment variables
  • Connection failures
  • Database operations
  • Embedding generation issues

Integration Example

@Injectable()
export class DocumentSearchService {
  constructor(private readonly pineconeService: PineconeService) {}

  async searchDocuments(userId: string, query: string, limit: number = 5) {
    try {
      // Get the user's vector store
      const vectorStore = await this.pineconeService.getVectorStore(userId);

      // Perform similarity search
      const results = await vectorStore.similaritySearch(query, limit);

      return {
        documents: results.map((doc) => ({
          content: doc.pageContent,
          metadata: doc.metadata,
        })),
        status: "success",
      };
    } catch (error) {
      this.logger.error("Document search failed", error);
      return {
        status: "error",
        message: "Failed to search documents",
      };
    }
  }
}