generated from cloudwego/.github
-
Notifications
You must be signed in to change notification settings - Fork 242
feat(milvus2): add milvus2 indexer and retriever components #628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 11 commits
Commits
Show all changes
59 commits
Select commit
Hold shift + click to select a range
36bd05d
feat(milvus2): add milvus2 indexer and retriever components
kaijchen d2dbb66
add deprecated warning in old milvus
kaijchen 0a46d62
fix spell check
kaijchen 7b4ecab
support BM25 function
kaijchen d5409e3
Revert "add deprecated warning in old milvus"
kaijchen f665fe5
update 2.4 readme
kaijchen a69c2b8
Merge branch 'main' into milvus2
kaijchen 4b61f32
Merge branch 'main' into milvus2
hi-pender 94a08a7
update indexer README
kaijchen 19a1e42
document analyzer options
kaijchen 0986f30
add hybrid zh examples & rename bm25 example to hybrid
kaijchen a47b042
fix old milvus readme
kaijchen 9228dac
cleanup the index error checking logic
kaijchen 1ca3d23
separate sparse config and support BYOSV
kaijchen 01bd1b7
refactor function structure
kaijchen fb08b74
refactor sparse method naming and doc converter
kaijchen 9946d4c
refactor sparse indexbuilder
kaijchen 7c0018f
update README
kaijchen b46c0b7
update README
kaijchen f7f2120
fix example
kaijchen 88b93c8
fix ConsistencyLevel
kaijchen 38f5b07
update ConsistencyLevel defaults
kaijchen f3e9c0e
add sparse search mode
kaijchen 78b2275
add SparseVectorField in retriever
kaijchen 93c3ad9
set vector fields explicitly in examples
kaijchen d54058e
update examples to be more explicit
kaijchen 0d83790
refactor: split dense vector configs
kaijchen 29a5471
add sparse example
kaijchen ce2bc70
update comments
kaijchen 493f698
update readme
kaijchen 57e6d30
simplify store options
kaijchen 6a48f1a
fix readme
kaijchen e69b8c5
standardize score retrieval in examples
kaijchen 7e997ad
remove synchronous flush in indexer
kaijchen f081614
don't store score in metadata
kaijchen 522a83f
remove filtering in retriever
kaijchen cda70c5
hybrid search defaults to global TopK
kaijchen 692f98b
set output field default
kaijchen 515ee5e
use upsert for store
kaijchen d80db2c
add GPUIVFPQIndexBuilder
kaijchen 5b1cf59
document sparse method defaults
kaijchen 5f849e2
check index exist before creation
kaijchen 29b2486
refactor search mode for polymorphism
kaijchen f80a7e2
update comments in examples
kaijchen 9cc7cf8
fix example
kaijchen 70d57f5
use DocumentConverter in scalar search mode
kaijchen 4c882f9
fix metric type in range search
kaijchen cdc9ef1
improve iterator EOF check
kaijchen c938329
cleanup
kaijchen 831063f
cleanup
kaijchen e929417
validate hybrid search option
kaijchen fdd2f71
update README
kaijchen e3f4ab9
combine and fix hybrid test
kaijchen 7ecb7aa
improve coverage
kaijchen a75ad61
Merge branch 'main' into milvus2
kaijchen 293f730
move EmbedQuery to search_mode/utils
kaijchen a356579
update README
kaijchen cb409a5
update indexer README
kaijchen 6644f5a
Merge branch 'main' into milvus2
hi-pender File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ ot = "ot" | |
| OT = "OT" | ||
| typ = "typ" | ||
| Typ = "Typ" | ||
| Rabit = "Rabit" | ||
|
|
||
| [files] | ||
| extend-exclude = ["**/*.test.txt"] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,281 @@ | ||
| # Milvus 2.x Indexer | ||
|
|
||
| English | [中文](./README_zh.md) | ||
|
|
||
| This package provides a Milvus 2.x (V2 SDK) indexer implementation for the EINO framework. It enables document storage and vector indexing in Milvus. | ||
|
|
||
| > **Note**: This package requires **Milvus 2.5+** for server-side function support (e.g., BM25). | ||
|
|
||
| ## Features | ||
|
|
||
| - **Milvus V2 SDK**: Uses the latest `milvus-io/milvus/client/v2` SDK | ||
| - **Auto Collection Management**: Automatically creates collections and indexes when needed | ||
| - **Sparse Vector Support**: Support for server-side functions (e.g., BM25) for automatic sparse vector generation | ||
| - **Field Analysis**: Configurable analyzers for text fields | ||
| - **Flexible Index Types**: Supports multiple index builders (Auto, HNSW, IVF_FLAT, FLAT, etc.) | ||
| - **Custom Document Conversion**: Configurable document-to-column conversion | ||
|
|
||
| ## Installation | ||
|
|
||
| ```bash | ||
| go get github.com/cloudwego/eino-ext/components/indexer/milvus2 | ||
| ``` | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ```go | ||
| package main | ||
|
|
||
| import ( | ||
| "context" | ||
| "log" | ||
| "os" | ||
|
|
||
| "github.com/cloudwego/eino-ext/components/embedding/ark" | ||
| "github.com/cloudwego/eino/schema" | ||
| "github.com/milvus-io/milvus/client/v2/milvusclient" | ||
|
|
||
| milvus2 "github.com/cloudwego/eino-ext/components/indexer/milvus2" | ||
| ) | ||
|
|
||
| func main() { | ||
| // Get the environment variables | ||
| addr := os.Getenv("MILVUS_ADDR") | ||
| username := os.Getenv("MILVUS_USERNAME") | ||
| password := os.Getenv("MILVUS_PASSWORD") | ||
| arkApiKey := os.Getenv("ARK_API_KEY") | ||
| arkModel := os.Getenv("ARK_MODEL") | ||
|
|
||
| ctx := context.Background() | ||
|
|
||
| // Create an embedding model | ||
| emb, err := ark.NewEmbedder(ctx, &ark.EmbeddingConfig{ | ||
| APIKey: arkApiKey, | ||
| Model: arkModel, | ||
| }) | ||
| if err != nil { | ||
| log.Fatalf("Failed to create embedding: %v", err) | ||
| return | ||
| } | ||
|
|
||
| // Create an indexer | ||
| indexer, err := milvus2.NewIndexer(ctx, &milvus2.IndexerConfig{ | ||
| ClientConfig: &milvusclient.ClientConfig{ | ||
| Address: addr, | ||
| Username: username, | ||
| Password: password, | ||
| }, | ||
| Collection: "my_collection", | ||
| Dimension: 1024, // Match your embedding model dimension | ||
| MetricType: milvus2.COSINE, | ||
| IndexBuilder: milvus2.NewHNSWIndexBuilder().WithM(16).WithEfConstruction(200), | ||
| Embedding: emb, | ||
| }) | ||
| if err != nil { | ||
| log.Fatalf("Failed to create indexer: %v", err) | ||
| return | ||
| } | ||
| log.Printf("Indexer created successfully") | ||
|
|
||
| // Store documents | ||
| docs := []*schema.Document{ | ||
| { | ||
| ID: "doc1", | ||
| Content: "Milvus is an open-source vector database", | ||
| MetaData: map[string]any{ | ||
| "category": "database", | ||
| "year": 2021, | ||
| }, | ||
| }, | ||
| { | ||
| ID: "doc2", | ||
| Content: "EINO is a framework for building AI applications", | ||
| }, | ||
| } | ||
| ids, err := indexer.Store(ctx, docs) | ||
| if err != nil { | ||
| log.Fatalf("Failed to store: %v", err) | ||
| return | ||
| } | ||
| log.Printf("Store success, ids: %v", ids) | ||
| } | ||
| ``` | ||
|
|
||
| ## Configuration | ||
|
|
||
| | Field | Type | Default | Description | | ||
| |-------|------|---------|-------------| | ||
| | `Client` | `*milvusclient.Client` | - | Pre-configured Milvus client (optional) | | ||
| | `ClientConfig` | `*milvusclient.ClientConfig` | - | Client configuration (required if Client is nil) | | ||
| | `Collection` | `string` | `"eino_collection"` | Collection name | | ||
| | `Dimension` | `int64` | - | Vector dimension (required for new collections) | | ||
| | `VectorField` | `string` | `"vector"` | Vector field name | | ||
| | `MetricType` | `MetricType` | `L2` | Similarity metric (L2, IP, COSINE, etc.) | | ||
| | `IndexBuilder` | `IndexBuilder` | AutoIndex | Index type builder | | ||
| | `Embedding` | `embedding.Embedder` | - | Embedder for vectorization (optional). If nil, documents must have vectors. | | ||
| | `ConsistencyLevel` | `ConsistencyLevel` | `Bounded` | Read consistency level | | ||
| | `PartitionName` | `string` | - | Default partition for insertion | | ||
| | `EnableDynamicSchema` | `bool` | `false` | Enable dynamic field support | | ||
| | `SparseVectorField` | `string` | - | Sparse vector field name (required for server-side function output) | | ||
| | `SparseIndexBuilder` | `SparseIndexBuilder` | SPARSE_INVERTED | Sparse index builder | | ||
| | `SparseMetricType` | `MetricType` | `IP` | Metric type for sparse index (IP, BM25) | | ||
| | `Functions` | `[]*entity.Function` | - | Schema functions (e.g., BM25) for server-side processing (e.g., generating sparse vectors from content) | | ||
| | `FieldParams` | `map[string]map[string]string` | - | Parameters for fields (e.g., enable_analyzer) | | ||
|
|
||
| ## Index Builders | ||
|
|
||
| | Builder | Description | Key Parameters | | ||
| |---------|-------------|----------------| | ||
| | `NewAutoIndexBuilder()` | Milvus auto-selects optimal index | - | | ||
| | `NewHNSWIndexBuilder()` | Graph-based with excellent performance | `M`, `EfConstruction` | | ||
| | `NewIVFFlatIndexBuilder()` | Cluster-based search | `NList` | | ||
| | `NewIVFPQIndexBuilder()` | Memory-efficient with product quantization | `NList`, `M`, `NBits` | | ||
| | `NewIVFSQ8IndexBuilder()` | Scalar quantization | `NList` | | ||
| | `NewIVFRabitQIndexBuilder()` | IVF + RaBitQ binary quantization (Milvus 2.6+) | `NList` | | ||
| | `NewFlatIndexBuilder()` | Brute-force exact search | - | | ||
| | `NewDiskANNIndexBuilder()` | Disk-based for large datasets | - | | ||
| | `NewSCANNIndexBuilder()` | Fast with high recall | `NList`, `WithReorder` | | ||
|
|
||
| #### Sparse Index Builders | ||
|
|
||
| | Builder | Description | Key Parameters | | ||
| |---------|-------------|----------------| | ||
| | `NewSparseInvertedIndexBuilder()` | Inverted index for sparse vectors | `DropRatioBuild` | | ||
| | `NewSparseWANDIndexBuilder()` | WAND algorithm for sparse vectors | `DropRatioBuild` | | ||
|
|
||
| ### Example: HNSW Index | ||
|
|
||
| ```go | ||
| indexBuilder := milvus2.NewHNSWIndexBuilder(). | ||
| WithM(16). // Max connections per node (4-64) | ||
| WithEfConstruction(200) // Index build search width (8-512) | ||
| ``` | ||
|
|
||
| ### Example: IVF_FLAT Index | ||
|
|
||
| ```go | ||
| indexBuilder := milvus2.NewIVFFlatIndexBuilder(). | ||
| WithNList(256) // Number of cluster units (1-65536) | ||
| ``` | ||
|
|
||
| ### Example: IVF_PQ Index (Memory-efficient) | ||
|
|
||
| ```go | ||
| indexBuilder := milvus2.NewIVFPQIndexBuilder(). | ||
| WithNList(256). // Number of cluster units | ||
| WithM(16). // Number of subquantizers | ||
| WithNBits(8) // Bits per subquantizer (1-16) | ||
| ``` | ||
|
|
||
| ### Example: SCANN Index (Fast with high recall) | ||
|
|
||
| ```go | ||
| indexBuilder := milvus2.NewSCANNIndexBuilder(). | ||
| WithNList(256). // Number of cluster units | ||
| WithRawDataEnabled(true) // Enable raw data for reranking | ||
| ``` | ||
|
|
||
| ### Example: DiskANN Index (Large datasets) | ||
|
|
||
| ```go | ||
| indexBuilder := milvus2.NewDiskANNIndexBuilder() // Disk-based, no extra params | ||
| ``` | ||
|
|
||
| ## Metric Types | ||
|
|
||
| | Metric | Description | | ||
| |--------|-------------| | ||
| | `L2` | Euclidean distance | | ||
| | `IP` | Inner Product | | ||
| | `COSINE` | Cosine similarity | | ||
| | `HAMMING` | Hamming distance (binary) | | ||
| | `JACCARD` | Jaccard distance (binary) | | ||
|
|
||
| ## Examples | ||
|
|
||
| See the [examples](./examples) directory for complete working examples: | ||
|
|
||
| - [demo](./examples/demo) - Basic collection setup with HNSW index | ||
| - [hnsw](./examples/hnsw) - HNSW index example | ||
| - [ivf_flat](./examples/ivf_flat) - IVF_FLAT index example | ||
| - [rabitq](./examples/rabitq) - IVF_RABITQ index example (Milvus 2.6+) | ||
| - [auto](./examples/auto) - AutoIndex example | ||
| - [diskann](./examples/diskann) - DISKANN index example | ||
| - [hybrid](./examples/hybrid) - Hybrid search setup (Dense + BM25 sparse) (Milvus 2.5+) | ||
| - [hybrid_chinese](./examples/hybrid_chinese) - Hybrid search with Chinese analyzer (Milvus 2.5+) | ||
| - [byov](./examples/byov) - Bring Your Own Vectors example | ||
|
|
||
| ### Sparse Vector Support | ||
|
|
||
| Use Milvus server-side functions (e.g., BM25) to automatically generate sparse vectors from text content: | ||
|
|
||
| ```go | ||
| // Define BM25 function | ||
| bm25Function := entity.NewFunction(). | ||
| WithName("bm25_fn"). | ||
| WithType(entity.FunctionTypeBM25). | ||
| WithInputFields("content"). // Input text field | ||
| WithOutputFields("sparse_vector") // Output sparse vector field | ||
|
|
||
| // Create indexer with function | ||
| indexer, err := milvus2.NewIndexer(ctx, &milvus2.IndexerConfig{ | ||
| // ... basic config ... | ||
| Collection: "hybrid_collection", | ||
|
|
||
| // Enable sparse vector support | ||
| SparseVectorField: "sparse_vector", | ||
| SparseMetricType: milvus2.BM25, | ||
|
|
||
| // Register function | ||
| Functions: []*entity.Function{bm25Function}, | ||
|
|
||
| // BM25 requires analyzer on content field. | ||
| // Analyzer options (built-in): | ||
| // - {"type": "standard"} - general-purpose, tokenization + lowercase | ||
| // - {"type": "english"} - English with stopwords support | ||
| // - {"type": "chinese"} - Chinese with Jieba segmentation | ||
| // - Custom: {"tokenizer": "...", "filter": [...]} | ||
| // See: https://milvus.io/docs/analyzer-overview.md | ||
| FieldParams: map[string]map[string]string{ | ||
| "content": { | ||
| "enable_analyzer": "true", | ||
| "analyzer_params": `{"type": "standard"}`, // Use {"type": "chinese"} for Chinese text | ||
| }, | ||
| }, | ||
| }) | ||
| ``` | ||
|
|
||
| ### Bring Your Own Vectors (BYOV) | ||
|
|
||
| You can use the indexer without an embedder if your documents already have vectors. | ||
|
|
||
| ```go | ||
| // Create indexer without embedding | ||
| indexer, err := milvus2.NewIndexer(ctx, &milvus2.IndexerConfig{ | ||
| ClientConfig: &milvusclient.ClientConfig{ | ||
| Address: "localhost:19530", | ||
| }, | ||
| Collection: "my_collection", | ||
| Dimension: 128, | ||
| // Embedding: nil, // Leave nil | ||
| }) | ||
|
|
||
| // Store documents with pre-computed vectors | ||
| docs := []*schema.Document{ | ||
| { | ||
| ID: "doc1", | ||
| Content: "Document with existing vector", | ||
| }, | ||
| } | ||
|
|
||
| // Attach vector to document | ||
| // Vector dimension must match the collection dimension | ||
| vector := []float64{0.1, 0.2, ...} | ||
| docs[0].WithDenseVector(vector) | ||
|
|
||
| ids, err := indexer.Store(ctx, docs) | ||
| ``` | ||
|
|
||
| ## License | ||
|
|
||
| Apache License 2.0 |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.