*   [](/v0.2/)
*   [How-to guides](/v0.2/docs/how_to/)
*   Hybrid Search

On this page

Hybrid Search
=============

The standard search in LangChain is done by vector similarity. However, a number of vectorstores implementations (Astra DB, ElasticSearch, Neo4J, AzureSearch, ...) also support more advanced search combining vector similarity search and other search techniques (full-text, BM25, and so on). This is generally referred to as "Hybrid" search.

**Step 1: Make sure the vectorstore you are using supports hybrid search**

At the moment, there is no unified way to perform hybrid search in LangChain. Each vectorstore may have their own way to do it. This is generally exposed as a keyword argument that is passed in during `similarity_search`. By reading the documentation or source code, figure out whether the vectorstore you are using supports hybrid search, and, if so, how to use it.

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

This will let you easily call the chain and configure any relevant flags at runtime. See [this documentation](/v0.2/docs/how_to/configure/) for more information on configuration.

**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 the Cassandra/CQL interface of Astra DB for this example.

Install the following Python package:

    !pip install "cassio>=0.1.7"

Get the [connection secrets](https://docs.datastax.com/en/astra/astra-db-vector/get-started/quickstart.html).

Initialize cassio:

    import cassiocassio.init(    database_id="Your database ID",    token="Your application token",    keyspace="Your key space",)

Create the Cassandra VectorStore with a standard [index analyzer](https://docs.datastax.com/en/astra/astra-db-vector/cql/use-analyzers-with-cql.html). The index analyzer is needed to enable term matching.

    from cassio.table.cql import STANDARD_ANALYZERfrom langchain_community.vectorstores import Cassandrafrom langchain_openai import OpenAIEmbeddingsembeddings = OpenAIEmbeddings()vectorstore = Cassandra(    embedding=embeddings,    table_name="test_hybrid",    body_index_options=[STANDARD_ANALYZER],    session=None,    keyspace=None,)vectorstore.add_texts(    [        "In 2023, I visited Paris",        "In 2022, I visited New York",        "In 2021, I visited New Orleans",    ])

**API Reference:**[Cassandra](https://api.python.langchain.com/en/latest/vectorstores/langchain_community.vectorstores.cassandra.Cassandra.html) | [OpenAIEmbeddings](https://api.python.langchain.com/en/latest/embeddings/langchain_openai.embeddings.base.OpenAIEmbeddings.html)

If we do a standard similarity search, we get all the documents:

    vectorstore.as_retriever().invoke("What city did I visit last?")

    [Document(page_content='In 2022, I visited New York'),Document(page_content='In 2023, I visited Paris'),Document(page_content='In 2021, I visited New Orleans')]

The Astra DB vectorstore `body_search` argument can be used to filter the search on the term `new`.

    vectorstore.as_retriever(search_kwargs={"body_search": "new"}).invoke(    "What city did I visit last?")

    [Document(page_content='In 2022, I visited New York'),Document(page_content='In 2021, I visited New Orleans')]

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

    from langchain_core.output_parsers import StrOutputParserfrom langchain_core.prompts import ChatPromptTemplatefrom langchain_core.runnables import (    ConfigurableField,    RunnablePassthrough,)from langchain_openai import ChatOpenAI

**API Reference:**[StrOutputParser](https://api.python.langchain.com/en/latest/output_parsers/langchain_core.output_parsers.string.StrOutputParser.html) | [ChatPromptTemplate](https://api.python.langchain.com/en/latest/prompts/langchain_core.prompts.chat.ChatPromptTemplate.html) | [ConfigurableField](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.utils.ConfigurableField.html) | [RunnablePassthrough](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.passthrough.RunnablePassthrough.html) | [ChatOpenAI](https://api.python.langchain.com/en/latest/chat_models/langchain_openai.chat_models.base.ChatOpenAI.html)

This is basic question-answering chain set up.

    template = """Answer the question based only on the following context:{context}Question: {question}"""prompt = ChatPromptTemplate.from_template(template)model = ChatOpenAI()retriever = vectorstore.as_retriever()

Here we mark the retriever as having a configurable field. All vectorstore retrievers have `search_kwargs` as a field. This is just a dictionary, with vectorstore specific fields

    configurable_retriever = retriever.configurable_fields(    search_kwargs=ConfigurableField(        id="search_kwargs",        name="Search Kwargs",        description="The search kwargs to use",    ))

We can now create the chain using our configurable retriever

    chain = (    {"context": configurable_retriever, "question": RunnablePassthrough()}    | prompt    | model    | StrOutputParser())

    chain.invoke("What city did I visit last?")

    Paris

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 Astra DB.

    chain.invoke(    "What city did I visit last?",    config={"configurable": {"search_kwargs": {"body_search": "new"}}},)

    New York

[Edit this page](https://github.com/langchain-ai/langchain/edit/master/docs/docs/how_to/hybrid.ipynb)

* * *

#### Was this page helpful?

  

#### You can also leave detailed feedback [on GitHub](https://github.com/langchain-ai/langchain/issues/new?assignees=&labels=03+-+Documentation&projects=&template=documentation.yml&title=DOC%3A+%3CPlease+write+a+comprehensive+title+after+the+%27DOC%3A+%27+prefix%3E).

[

Previous

How to filter messages

](/v0.2/docs/how_to/filter_messages/)[

Next

How to use the LangChain indexing API

](/v0.2/docs/how_to/indexing/)

*   [Code Example](#code-example)