!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}return t}()||function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}(),document.documentElement.setAttribute("data-announcement-bar-initially-dismissed",function(){try{return"true"===localStorage.getItem("docusaurus.announcement.dismiss")}catch(t){}return!1}())

[Skip to main content](#__docusaurus_skipToContent_fallback)

LangChain v0.2 is coming soon! Preview the new docs [here](/v0.2/docs/introduction/).

[

![🦜️🔗 Langchain](/v0.1/img/brand/wordmark.png)![🦜️🔗 Langchain](/v0.1/img/brand/wordmark-dark.png)

](/v0.1/)[Docs](/v0.1/docs/get_started/introduction/)[Use cases](/v0.1/docs/use_cases/)[Integrations](/v0.1/docs/integrations/platforms/)[API Reference](https://api.js.langchain.com)

[More](#)

*   [People](/v0.1/docs/people/)
*   [Community](/v0.1/docs/community/)
*   [Tutorials](/v0.1/docs/additional_resources/tutorials/)
*   [Contributing](/v0.1/docs/contributing/)

[v0.1](#)

*   [v0.2](https://js.langchain.com/v0.2/docs/introduction)
*   [v0.1](/v0.1/docs/get_started/introduction/)

[🦜🔗](#)

*   [LangSmith](https://smith.langchain.com)
*   [LangSmith Docs](https://docs.smith.langchain.com)
*   [LangChain Hub](https://smith.langchain.com/hub)
*   [LangServe](https://github.com/langchain-ai/langserve)
*   [Python Docs](https://python.langchain.com/)

[Chat](https://chatjs.langchain.com)[](https://github.com/langchain-ai/langchainjs)

Search

*   [Use cases](/v0.1/docs/use_cases/)
    
    *   [SQL](/v0.1/docs/use_cases/sql/)
        
    *   [Chatbots](/v0.1/docs/use_cases/chatbots/)
        
    *   [Extraction](/v0.1/docs/use_cases/extraction/)
        
    *   [Query Analysis](/v0.1/docs/use_cases/query_analysis/)
        
    *   [Q&A with RAG](/v0.1/docs/use_cases/question_answering/)
        
        *   [Quickstart](/v0.1/docs/use_cases/question_answering/quickstart/)
        *   [Per-User Retrieval](/v0.1/docs/use_cases/question_answering/per_user/)
        *   [Add chat history](/v0.1/docs/use_cases/question_answering/chat_history/)
        *   [Citations](/v0.1/docs/use_cases/question_answering/citations/)
        *   [Using agents](/v0.1/docs/use_cases/question_answering/conversational_retrieval_agents/)
        *   [Using local models](/v0.1/docs/use_cases/question_answering/local_retrieval_qa/)
        *   [Returning sources](/v0.1/docs/use_cases/question_answering/sources/)
        *   [Streaming](/v0.1/docs/use_cases/question_answering/streaming/)
    *   [Tool use](/v0.1/docs/use_cases/tool_use/)
        
    *   [Interacting with APIs](/v0.1/docs/use_cases/api/)
    *   [Tabular Question Answering](/v0.1/docs/use_cases/tabular/)
    *   [Graphs](/v0.1/docs/use_cases/graph/)
        
    *   [Summarization](/v0.1/docs/use_cases/summarization/)
    *   [Agent Simulations](/v0.1/docs/use_cases/agent_simulations/)
        
    *   [Autonomous Agents](/v0.1/docs/use_cases/autonomous_agents/)
        
    *   [Code Understanding](/v0.1/docs/use_cases/code_understanding/)
    *   [Audio/Video Structured Extraction](/v0.1/docs/use_cases/media/)

*   [](/v0.1/)
*   [Use cases](/v0.1/docs/use_cases/)
*   [Q&A with RAG](/v0.1/docs/use_cases/question_answering/)
*   Per-User Retrieval

On this page

Per-User Retrieval
==================

When building a retrieval app, you often have to build it with multiple users in mind. This means that you may be storing data not just for one user, but for many different users, and they should not be able to see eachother’s data. This means that you need to be able to configure your retrieval chain to only retrieve certain information. This generally involves two steps.

**Step 1: Make sure the retriever you are using supports multiple users**

At the moment, there is no unified flag or filter for this in LangChain. Rather, each vectorstore and retriever may have their own, and may be called different things (namespaces, multi-tenancy, etc). For vectorstores, this is generally exposed as a keyword argument that is passed in during `similaritySearch`. By reading the documentation or source code, figure out whether the retriever you are using supports multiple users, and, if so, how to use it.

Note: adding documentation and/or support for multiple users for retrievers that do not support it (or document it) is a GREAT way to contribute to LangChain

**Step 2: Add that parameter as a configurable field for the chain**

The LangChain `config` object is passed through to every Runnable. Here you can add any fields you’d like to the `configurable` object. Later, inside the chain we can extract these fields.

**Step 3: Call the chain with that configurable field**

Now, at runtime you can call this chain with configurable field.

Code Example[​](#code-example "Direct link to Code Example")
------------------------------------------------------------

Let’s see a concrete example of what this looks like in code. We will use Pinecone for this example.

Setup[​](#setup "Direct link to Setup")
---------------------------------------

### Install dependencies[​](#install-dependencies "Direct link to Install dependencies")

tip

See [this section for general instructions on installing integration packages](/v0.1/docs/get_started/installation/#installing-integration-packages).

*   npm
*   yarn
*   pnpm

    npm i @langchain/pinecone @langchain/openai @pinecone-database/pinecone @langchain/core

    yarn add @langchain/pinecone @langchain/openai @pinecone-database/pinecone @langchain/core

    pnpm add @langchain/pinecone @langchain/openai @pinecone-database/pinecone @langchain/core

### Set environment variables[​](#set-environment-variables "Direct link to Set environment variables")

We’ll use OpenAI and Pinecone in this example:

    OPENAI_API_KEY=your-api-keyPINECONE_API_KEY=your-api-keyPINECONE_INDEX=your-index-name# Optional, use LangSmith for best-in-class observabilityLANGSMITH_API_KEY=your-api-keyLANGCHAIN_TRACING_V2=true

    import { OpenAIEmbeddings } from "@langchain/openai";import { PineconeStore } from "@langchain/pinecone";import { Pinecone } from "@pinecone-database/pinecone";import { Document } from "@langchain/core/documents";

    const embeddings = new OpenAIEmbeddings();const pinecone = new Pinecone();const pineconeIndex = pinecone.Index(Deno.env.get("PINECONE_INDEX"));const vectorStore = await PineconeStore.fromExistingIndex(  new OpenAIEmbeddings(),  { pineconeIndex });

    await vectorStore.addDocuments(  [new Document({ pageContent: "i worked at kensho" })],  { namespace: "harrison" });

    [ "39d90a6d-7e97-45cc-a9dc-ebefa47220fc" ]

    await vectorStore.addDocuments(  [new Document({ pageContent: "i worked at facebook" })],  { namespace: "ankush" });

    [ "75f94962-9135-4385-b71c-36d8345e02aa" ]

The pinecone kwarg for `namespace` can be used to separate documents

    // This will only get documents for Ankushawait vectorStore  .asRetriever({    filter: {      namespace: "ankush",    },  })  .getRelevantDocuments("where did i work?");

    [ Document { pageContent: "i worked at facebook", metadata: {} } ]

    // This will only get documents for Harrisonawait vectorStore  .asRetriever({    filter: {      namespace: "harrison",    },  })  .getRelevantDocuments("where did i work?");

    [ Document { pageContent: "i worked at kensho", metadata: {} } ]

We can now create the chain that we will use to do question-answering over

    import { StringOutputParser } from "@langchain/core/output_parsers";import { ChatPromptTemplate } from "@langchain/core/prompts";import {  RunnableBinding,  RunnableLambda,  RunnablePassthrough,} from "@langchain/core/runnables";import { ChatOpenAI, OpenAIEmbeddings } from "@langchain/openai";

This is basic question-answering chain set up.

    const template = `Answer the question based only on the following context:{context}Question: {question}`;const prompt = ChatPromptTemplate.fromTemplate(template);const model = new ChatOpenAI({  model: "gpt-3.5-turbo-0125",  temperature: 0,});const retriever = vectorStore.asRetriever();

We can now create the chain using our configurable retriever. It is configurable because we can define any object which will be passed to the chain. From there, we extract the configurable object and pass it to the vectorstore.

    import { RunnableSequence } from "@langchain/core/runnables";const chain = RunnableSequence.from([  {    context: async (input, config) => {      if (!config || !("configurable" in config)) {        throw new Error("No config");      }      const { configurable } = config;      return JSON.stringify(        await vectorStore.asRetriever(configurable).getRelevantDocuments(input)      );    },    question: new RunnablePassthrough(),  },  prompt,  model,  new StringOutputParser(),]);

We can now invoke the chain with configurable options. `search_kwargs` is the id of the configurable field. The value is the search kwargs to use for Pinecone

    await chain.invoke("where did the user work?", {  configurable: { filter: { namespace: "harrison" } },});

    "The user worked at Kensho."

    await chain.invoke("where did the user work?", {  configurable: { filter: { namespace: "ankush" } },});

    "The user worked at Facebook."

For more vectorstore implementations for multi-user, please refer to specific pages, such as [Milvus](/v0.1/docs/integrations/vectorstores/milvus/).

* * *

#### Help us out by providing feedback on this documentation page:

[

Previous

Quickstart

](/v0.1/docs/use_cases/question_answering/quickstart/)[

Next

Add chat history

](/v0.1/docs/use_cases/question_answering/chat_history/)

*   [Code Example](#code-example)
*   [Setup](#setup)
    *   [Install dependencies](#install-dependencies)
    *   [Set environment variables](#set-environment-variables)

Community

*   [Discord](https://discord.gg/cU2adEyC7w)
*   [Twitter](https://twitter.com/LangChainAI)

GitHub

*   [Python](https://github.com/langchain-ai/langchain)
*   [JS/TS](https://github.com/langchain-ai/langchainjs)

More

*   [Homepage](https://langchain.com)
*   [Blog](https://blog.langchain.dev)

Copyright © 2024 LangChain, Inc.