!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/)
        
        *   [Quickstart](/v0.1/docs/use_cases/query_analysis/quickstart/)
        *   [Techniques](/v0.1/docs/use_cases/query_analysis/techniques/decomposition/)
            
        *   [How-To Guides](/v0.1/docs/use_cases/query_analysis/how_to/few_shot/)
            
            *   [Add Examples to the Prompt](/v0.1/docs/use_cases/query_analysis/how_to/few_shot/)
            *   [Handle Cases Where No Queries are Generated](/v0.1/docs/use_cases/query_analysis/how_to/no_queries/)
            *   [Handle Multiple Queries](/v0.1/docs/use_cases/query_analysis/how_to/multiple_queries/)
            *   [Handle Multiple Retrievers](/v0.1/docs/use_cases/query_analysis/how_to/multiple_retrievers/)
            *   [Construct Filters](/v0.1/docs/use_cases/query_analysis/how_to/constructing_filters/)
            *   [Deal with High Cardinality Categoricals](/v0.1/docs/use_cases/query_analysis/how_to/high_cardinality/)
    *   [Q&A with RAG](/v0.1/docs/use_cases/question_answering/)
        
    *   [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/)
*   [Query Analysis](/v0.1/docs/use_cases/query_analysis/)
*   How-To Guides
*   Deal with High Cardinality Categoricals

On this page

Deal with High Cardinality Categoricals
=======================================

You may want to do query analysis to create a filter on a categorical column. One of the difficulties here is that you usually need to specify the EXACT categorical value. The issue is you need to make sure the LLM generates that categorical value exactly. This can be done relatively easy with prompting when there are only a few values that are valid. When there are a high number of valid values then it becomes more difficult, as those values may not fit in the LLM context, or (if they do) there may be too many for the LLM to properly attend to.

In this notebook we take a look at how to approach this.

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/core @langchain/community zod chromadb @faker-js/faker

    yarn add @langchain/core @langchain/community zod chromadb @faker-js/faker

    pnpm add @langchain/core @langchain/community zod chromadb @faker-js/faker

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

    # Optional, use LangSmith for best-in-class observabilityLANGSMITH_API_KEY=your-api-keyLANGCHAIN_TRACING_V2=true

#### Set up data[​](#set-up-data "Direct link to Set up data")

We will generate a bunch of fake names

    import { faker } from "@faker-js/faker";const names = Array.from({ length: 10000 }, () => faker.person.fullName());

Let’s look at some of the names

    names[0];

    "Dale Kessler"

    names[567];

    "Mrs. Chelsea Bayer MD"

Query Analysis[​](#query-analysis "Direct link to Query Analysis")
------------------------------------------------------------------

We can now set up a baseline query analysis

    import { z } from "zod";const searchSchema = z.object({  query: z.string(),  author: z.string(),});

### Pick your chat model:

*   OpenAI
*   Anthropic
*   FireworksAI
*   MistralAI

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/openai 

    yarn add @langchain/openai 

    pnpm add @langchain/openai 

#### Add environment variables

    OPENAI_API_KEY=your-api-key

#### Instantiate the model

    import { ChatOpenAI } from "@langchain/openai";const llm = new ChatOpenAI({  model: "gpt-3.5-turbo-0125",  temperature: 0});

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/anthropic 

    yarn add @langchain/anthropic 

    pnpm add @langchain/anthropic 

#### Add environment variables

    ANTHROPIC_API_KEY=your-api-key

#### Instantiate the model

    import { ChatAnthropic } from "@langchain/anthropic";const llm = new ChatAnthropic({  model: "claude-3-sonnet-20240229",  temperature: 0});

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/community 

    yarn add @langchain/community 

    pnpm add @langchain/community 

#### Add environment variables

    FIREWORKS_API_KEY=your-api-key

#### Instantiate the model

    import { ChatFireworks } from "@langchain/community/chat_models/fireworks";const llm = new ChatFireworks({  model: "accounts/fireworks/models/firefunction-v1",  temperature: 0});

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/mistralai 

    yarn add @langchain/mistralai 

    pnpm add @langchain/mistralai 

#### Add environment variables

    MISTRAL_API_KEY=your-api-key

#### Instantiate the model

    import { ChatMistralAI } from "@langchain/mistralai";const llm = new ChatMistralAI({  model: "mistral-large-latest",  temperature: 0});

    import { ChatPromptTemplate } from "@langchain/core/prompts";import {  RunnablePassthrough,  RunnableSequence,} from "@langchain/core/runnables";const system = `Generate a relevant search query for a library system`;const prompt = ChatPromptTemplate.fromMessages([  ["system", system],  ["human", "{question}"],]);const llmWithTools = llm.withStructuredOutput(searchSchema, {  name: "Search",});const queryAnalyzer = RunnableSequence.from([  {    question: new RunnablePassthrough(),  },  prompt,  llmWithTools,]);

We can see that if we spell the name exactly correctly, it knows how to handle it

    await queryAnalyzer.invoke("what are books about aliens by Jesse Knight");

    { query: "books about aliens", author: "Jesse Knight" }

The issue is that the values you want to filter on may NOT be spelled exactly correctly

    await queryAnalyzer.invoke("what are books about aliens by jess knight");

    { query: "books about aliens", author: "Jess Knight" }

### Add in all values[​](#add-in-all-values "Direct link to Add in all values")

One way around this is to add ALL possible values to the prompt. That will generally guide the query in the right direction

    const system = `Generate a relevant search query for a library system using the 'search' tool.The 'author' you return to the user MUST be one of the following authors:{authors}Do NOT hallucinate author name!`;const basePrompt = ChatPromptTemplate.fromMessages([  ["system", system],  ["human", "{question}"],]);const prompt = await basePrompt.partial({ authors: names.join(", ") });

    const queryAnalyzerAll = RunnableSequence.from([  {    question: new RunnablePassthrough(),  },  prompt,  llmWithTools,]);

However… if the list of categoricals is long enough, it may error!

    try {  const res = await queryAnalyzerAll.invoke(    "what are books about aliens by jess knight"  );} catch (e) {  console.error(e);}

    Error: 400 This model's maximum context length is 16385 tokens. However, your messages resulted in 49822 tokens (49792 in the messages, 30 in the functions). Please reduce the length of the messages or functions.    at Function.generate (file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/openai/4.28.4/error.mjs:40:20)    at OpenAI.makeStatusError (file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/openai/4.28.4/core.mjs:256:25)    at OpenAI.makeRequest (file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/openai/4.28.4/core.mjs:299:30)    at eventLoopTick (ext:core/01_core.js:63:7)    at async file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/@langchain/openai/0.0.15/dist/chat_models.js:650:29    at async RetryOperation._fn (file:///Users/bracesproul/Library/Caches/deno/npm/registry.npmjs.org/p-retry/4.6.2/index.js:50:12) {  status: 400,  headers: {    "access-control-allow-origin": "*",    "alt-svc": 'h3=":443"; ma=86400',    "cf-cache-status": "DYNAMIC",    "cf-ray": "85f6e713581815d0-SJC",    "content-length": "341",    "content-type": "application/json",    date: "Tue, 05 Mar 2024 03:08:39 GMT",    "openai-organization": "langchain",    "openai-processing-ms": "349",    "openai-version": "2020-10-01",    server: "cloudflare",    "set-cookie": "_cfuvid=NXe7nstRj6UNdFs5F8k49JZF6Tz7EE8dfKwYRpV3AWI-1709608119946-0.0.1.1-604800000; path=/; domain="... 48 more characters,    "strict-transport-security": "max-age=15724800; includeSubDomains",    "x-ratelimit-limit-requests": "10000",    "x-ratelimit-limit-tokens": "2000000",    "x-ratelimit-remaining-requests": "9999",    "x-ratelimit-remaining-tokens": "1958537",    "x-ratelimit-reset-requests": "6ms",    "x-ratelimit-reset-tokens": "1.243s",    "x-request-id": "req_99890749d442033c6145f9a8f1324aea"  },  error: {    message: "This model's maximum context length is 16385 tokens. However, your messages resulted in 49822 tokens"... 101 more characters,    type: "invalid_request_error",    param: "messages",    code: "context_length_exceeded"  },  code: "context_length_exceeded",  param: "messages",  type: "invalid_request_error",  attemptNumber: 1,  retriesLeft: 6}

We can try to use a longer context window… but with so much information in there, it is not garunteed to pick it up reliably

### Pick your chat model:

*   OpenAI
*   Anthropic
*   FireworksAI
*   MistralAI

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/openai 

    yarn add @langchain/openai 

    pnpm add @langchain/openai 

#### Add environment variables

    OPENAI_API_KEY=your-api-key

#### Instantiate the model

    import { ChatOpenAI } from "@langchain/openai";const llmLong = new ChatOpenAI({ model: "gpt-4-turbo-preview" });

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/anthropic 

    yarn add @langchain/anthropic 

    pnpm add @langchain/anthropic 

#### Add environment variables

    ANTHROPIC_API_KEY=your-api-key

#### Instantiate the model

    import { ChatAnthropic } from "@langchain/anthropic";const llmLong = new ChatAnthropic({  model: "claude-3-sonnet-20240229",  temperature: 0});

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/community 

    yarn add @langchain/community 

    pnpm add @langchain/community 

#### Add environment variables

    FIREWORKS_API_KEY=your-api-key

#### Instantiate the model

    import { ChatFireworks } from "@langchain/community/chat_models/fireworks";const llmLong = new ChatFireworks({  model: "accounts/fireworks/models/firefunction-v1",  temperature: 0});

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/mistralai 

    yarn add @langchain/mistralai 

    pnpm add @langchain/mistralai 

#### Add environment variables

    MISTRAL_API_KEY=your-api-key

#### Instantiate the model

    import { ChatMistralAI } from "@langchain/mistralai";const llmLong = new ChatMistralAI({  model: "mistral-large-latest",  temperature: 0});

    const structuredLlmLong = llmLong.withStructuredOutput(searchSchema, {  name: "Search",});const queryAnalyzerAll = RunnableSequence.from([  {    question: new RunnablePassthrough(),  },  prompt,  structuredLlmLong,]);

    await queryAnalyzerAll.invoke("what are books about aliens by jess knight");

    { query: "aliens", author: "Jess Knight" }

### Find and all relevant values[​](#find-and-all-relevant-values "Direct link to Find and all relevant values")

Instead, what we can do is create an index over the relevant values and then query that for the N most relevant values,

    import { Chroma } from "@langchain/community/vectorstores/chroma";import { OpenAIEmbeddings } from "@langchain/openai";import "chromadb";const embeddings = new OpenAIEmbeddings({  model: "text-embedding-3-small",});const vectorstore = await Chroma.fromTexts(names, {}, embeddings, {  collectionName: "author_names",});

    [Module: null prototype] {  AdminClient: [class AdminClient],  ChromaClient: [class ChromaClient],  CloudClient: [class CloudClient extends ChromaClient],  CohereEmbeddingFunction: [class CohereEmbeddingFunction],  Collection: [class Collection],  DefaultEmbeddingFunction: [class _DefaultEmbeddingFunction],  GoogleGenerativeAiEmbeddingFunction: [class _GoogleGenerativeAiEmbeddingFunction],  HuggingFaceEmbeddingServerFunction: [class HuggingFaceEmbeddingServerFunction],  IncludeEnum: {    Documents: "documents",    Embeddings: "embeddings",    Metadatas: "metadatas",    Distances: "distances"  },  JinaEmbeddingFunction: [class JinaEmbeddingFunction],  OpenAIEmbeddingFunction: [class _OpenAIEmbeddingFunction],  TransformersEmbeddingFunction: [class _TransformersEmbeddingFunction]}

    const selectNames = async (question: string) => {  const _docs = await vectorstore.similaritySearch(question, 10);  const _names = _docs.map((d) => d.pageContent);  return _names.join(", ");};

    const createPrompt = RunnableSequence.from([  {    question: new RunnablePassthrough(),    authors: selectNames,  },  basePrompt,]);

    const queryAnalyzerSelect = createPrompt.pipe(llmWithTools);

    await createPrompt.invoke("what are books by jess knight");

    ChatPromptValue {  lc_serializable: true,  lc_kwargs: {    messages: [      SystemMessage {        lc_serializable: true,        lc_kwargs: {          content: "Generate a relevant search query for a library system using the 'search' tool.\n" +            "\n" +            "The 'author' you ret"... 259 more characters,          additional_kwargs: {}        },        lc_namespace: [ "langchain_core", "messages" ],        content: "Generate a relevant search query for a library system using the 'search' tool.\n" +          "\n" +          "The 'author' you ret"... 259 more characters,        name: undefined,        additional_kwargs: {}      },      HumanMessage {        lc_serializable: true,        lc_kwargs: {          content: "what are books by jess knight",          additional_kwargs: {}        },        lc_namespace: [ "langchain_core", "messages" ],        content: "what are books by jess knight",        name: undefined,        additional_kwargs: {}      }    ]  },  lc_namespace: [ "langchain_core", "prompt_values" ],  messages: [    SystemMessage {      lc_serializable: true,      lc_kwargs: {        content: "Generate a relevant search query for a library system using the 'search' tool.\n" +          "\n" +          "The 'author' you ret"... 259 more characters,        additional_kwargs: {}      },      lc_namespace: [ "langchain_core", "messages" ],      content: "Generate a relevant search query for a library system using the 'search' tool.\n" +        "\n" +        "The 'author' you ret"... 259 more characters,      name: undefined,      additional_kwargs: {}    },    HumanMessage {      lc_serializable: true,      lc_kwargs: {        content: "what are books by jess knight",        additional_kwargs: {}      },      lc_namespace: [ "langchain_core", "messages" ],      content: "what are books by jess knight",      name: undefined,      additional_kwargs: {}    }  ]}

    await queryAnalyzerSelect.invoke("what are books about aliens by jess knight");

    { query: "books about aliens", author: "Jessica Kerluke" }

* * *

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

[

Previous

Construct Filters

](/v0.1/docs/use_cases/query_analysis/how_to/constructing_filters/)[

Next

Q&A with RAG

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

*   [Setup](#setup)
*   [Query Analysis](#query-analysis)
    *   [Add in all values](#add-in-all-values)
    *   [Find and all relevant values](#find-and-all-relevant-values)

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.