From 52a14caa30949ea05098b93c4439669799327df8 Mon Sep 17 00:00:00 2001 From: ChengZi Date: Fri, 28 Feb 2025 11:14:21 +0800 Subject: [PATCH] docs: refine milvus doc with hybrid-search Signed-off-by: ChengZi --- .../integrations/vectorstores/milvus.ipynb | 129 ++++++++++++++++-- 1 file changed, 115 insertions(+), 14 deletions(-) diff --git a/docs/docs/integrations/vectorstores/milvus.ipynb b/docs/docs/integrations/vectorstores/milvus.ipynb index e147541a04a21..6e115f55754ca 100644 --- a/docs/docs/integrations/vectorstores/milvus.ipynb +++ b/docs/docs/integrations/vectorstores/milvus.ipynb @@ -206,7 +206,7 @@ "source": [ "Note the change in the URI below. Once the instance is initialized, navigate to http://127.0.0.1:9091/webui to view the local web UI.\n", "\n", - "Here is an example of how you would use a dense embedding + the Milvus BM25 built-in function to assemble a hybrid retrieval vector store instance:" + "Here is an example of how you create your vector store instance with the Milvus database serivce:" ] }, { @@ -218,28 +218,25 @@ "source": [ "from langchain_milvus import BM25BuiltInFunction, Milvus\n", "\n", - "dense_index_param = {\n", - " \"metric_type\": \"COSINE\",\n", - " \"index_type\": \"HNSW\",\n", - "}\n", - "sparse_index_param = {\n", - " \"metric_type\": \"BM25\",\n", - " \"index_type\": \"AUTOINDEX\",\n", - "}\n", - "\n", "URI = \"http://localhost:19530\"\n", "\n", "vectorstore = Milvus(\n", " embedding_function=embeddings,\n", - " builtin_function=BM25BuiltInFunction(output_field_names=\"sparse\"),\n", - " index_params=[dense_index_param, sparse_index_param],\n", - " vector_field=[\"dense\", \"sparse\"],\n", " connection_args={\"uri\": URI, \"token\": \"root:Milvus\", \"db_name\": \"milvus_demo\"},\n", + " index_params={\"index_type\": \"FLAT\", \"metric_type\": \"L2\"},\n", " consistency_level=\"Strong\",\n", " drop_old=False, # set to True if seeking to drop the collection with that name if it exists\n", ")" ] }, + { + "cell_type": "markdown", + "id": "6d5a9670", + "metadata": {}, + "source": [ + "> If you want to use Zilliz Cloud, the fully managed cloud service for Milvus, please adjust the uri and token, which correspond to the [Public Endpoint](https://docs.zilliz.com/docs/byoc/quick-start#free-cluster-details) and [Api key](https://docs.zilliz.com/docs/byoc/quick-start#free-cluster-details) in Zilliz Cloud." + ] + }, { "cell_type": "markdown", "id": "cae1a7d5", @@ -552,6 +549,110 @@ "retriever.invoke(\"Stealing from the bank is a crime\", filter={\"source\": \"news\"})" ] }, + { + "cell_type": "markdown", + "id": "8edb47106e1a46a883d545849b8ab81b", + "metadata": { + "collapsed": false + }, + "source": [ + "\n", + "## Hybrid Search\n", + "\n", + "The most common hybrid search scenario is the dense + sparse hybrid search, where candidates are retrieved using both semantic vector similarity and precise keyword matching. Results from these methods are merged, reranked, and passed to an LLM to generate the final answer. This approach balances precision and semantic understanding, making it highly effective for diverse query scenarios.\n", + "\n", + "\n", + "### Full-text search\n", + "Since [Milvus 2.5](https://milvus.io/blog/introduce-milvus-2-5-full-text-search-powerful-metadata-filtering-and-more.md), full-text search is natively supported through the Sparse-BM25 approach, by representing the BM25 algorithm as sparse vectors. Milvus accepts raw text as input and automatically converts it into sparse vectors stored in a specified field, eliminating the need for manual sparse embedding generation.\n", + "\n", + "For full-text search Milvus VectorStore accepts a `builtin_function` parameter. Through this parameter, you can pass in an instance of the `BM25BuiltInFunction`. This is different than semantic search which usually passes dense embeddings to the `VectorStore`,\n", + "\n", + "Here is a simple example of hybrid search in Milvus with OpenAI dense embedding for semantic search and BM25 for full-text search:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "10185d26023b46108eb7d9f57d49d2b3", + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "from langchain_milvus import BM25BuiltInFunction, Milvus\n", + "from langchain_openai import OpenAIEmbeddings\n", + "\n", + "vectorstore = Milvus.from_documents(\n", + " documents=documents,\n", + " embedding=OpenAIEmbeddings(),\n", + " builtin_function=BM25BuiltInFunction(),\n", + " # `dense` is for OpenAI embeddings, `sparse` is the output field of BM25 function\n", + " vector_field=[\"dense\", \"sparse\"],\n", + " connection_args={\n", + " \"uri\": URI,\n", + " },\n", + " consistency_level=\"Strong\",\n", + " drop_old=True,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "8763a12b2bbd4a93a75aff182afb95dc", + "metadata": { + "collapsed": false + }, + "source": [ + "> - When you use `BM25BuiltInFunction`, please note that the full-text search is available in Milvus Standalone and Milvus Distributed, but not in Milvus Lite, although it is on the roadmap for future inclusion. It will also be available in Zilliz Cloud (fully-managed Milvus) soon. Please reach out to support@zilliz.com for more information.\n", + "\n", + "In the code above, we define an instance of `BM25BuiltInFunction` and pass it to the `Milvus` object. `BM25BuiltInFunction` is a lightweight wrapper class for [`Function`](https://milvus.io/docs/manage-collections.md#Function) in Milvus. We can use it with `OpenAIEmbeddings` to initialize a dense + sparse hybrid search Milvus vector store instance.\n", + "\n", + "`BM25BuiltInFunction` does not require the client to pass corpus or training, all are automatically processed at the Milvus server's end, so users do not need to care about any vocabulary and corpus. In addition, users can also customize the [analyzer](https://milvus.io/docs/analyzer-overview.md#Analyzer-Overview) to implement the custom text processing in the BM25." + ] + }, + { + "cell_type": "markdown", + "id": "7623eae2785240b9bd12b16a66d81610", + "metadata": { + "collapsed": false + }, + "source": [ + "### Rerank the candidates\n", + "After the first stage of retrieval, we need to rerank the candidates to get a better result. You can refer to the [Reranking](https://milvus.io/docs/reranking.md#Reranking) for more information.\n", + "\n", + "Here is an example for weighted reranking:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7cdc8c89c7104fffa095e18ddfef8986", + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "query = \"What are the novels Lila has written and what are their contents?\"\n", + "\n", + "vectorstore.similarity_search(\n", + " query, k=1, ranker_type=\"weighted\", ranker_params={\"weights\": [0.6, 0.4]}\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "b3965036", + "metadata": {}, + "source": [ + "For more information about Full-text search and Hybrid search, please refer to the [Using Full-Text Search with LangChain and Milvus](https://milvus.io/docs/full_text_search_with_langchain.md) and [Hybrid Retrieval with LangChain and Milvus](https://milvus.io/docs/milvus_hybrid_search_retriever.md)." + ] + }, { "cell_type": "markdown", "id": "8ac953f1", @@ -726,7 +827,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.10.0" } }, "nbformat": 4,