Where should the client/server line sit for a SQL layer over Milvus after 3.0? #52546
|
Hi all. I've been building Two things motivated it. First, teams already sitting on SQLAlchemy or Django who want vector Milvus 3.0 changes the calculus for a layer like this, and I'd rather find out now that I'm Where the line currently sitsSingle-collection statements are one RPC and never materialize a DataFrame — a filter SELECT id, content FROM docs ORDER BY embedding <=> :q LIMIT 10Anything needing more than one collection is planned into one Milvus read per collection and The key pushdown is what keeps it honest: an ANN search returning 50 hits joined against a Worth stating plainly before anyone opens the repo: everything above is 2.6.x. The The questions1. How much of the relational surface do you expect to land server-side over 3.1? 2. Is cross-collection 3. Does a DBAPI-shaped interface fill a real gap, or does Spark DataSource v2 cover it? 4. How should a SQL dialect express 3.0's first-class content TEXT,
content_sparse SPARSEVEC GENERATED ALWAYS AS (BM25(content))which spells out the schema One observation I'd offer rather than a request: Happy to be told the design is wrong — that's the more useful outcome of the two. If any of it |
Replies: 5 comments
|
|
@yhmo — thank you, this is exactly what I needed, and more concrete than I expected. Marking your reply as the answer and closing the thread. Three things changed on my side as a direct result: The 2.6 → 3.0 path is a migration, not a port. That reframing is the most useful part of your answer. I was treating 3.0 as a wall; it's a gradient. The README now carries a compatibility table that says exactly this — 2.6 client works against a 3.0 server, 3.0-only capabilities need the 3.x client line. I'm restructuring around a server-capability layer rather than special-casing 3.0. Single-collection
One thing I ran into while working through Q1 that may be worth flagging internally, since it bites anything putting SQL semantics on top: query aggregation and search aggregation have different accuracy guarantees. Query aggregation is exact over filtered data; search aggregation is documented as approximate, computed over ANN-retrieved entities. A SQL Thanks again for taking the time on all four. |
|
Thanks for raising these questions — this is very much aligned with how we are thinking about the boundary between Milvus and higher-level SQL interfaces.
On your Conceptually: ROW_NUMBER() OVER (
PARTITION BY category
ORDER BY distance
)with a filter such as The SQL window-function syntax is of course more general than the Milvus search API, but for this particular ANN top-k-per-group semantic, I would map it to Grouping Search rather than to search facets. Facets are more about statistics/aggregation over buckets, while Grouping Search directly affects which search results are returned per group. Overall, I think there is a useful role for a SQL layer here. The boundary I would suggest is: push single-collection filtering, sorting, aggregation, grouping, vector search, and similar operators into Milvus whenever Milvus has native semantics for them; keep the SQL layer focused on compatibility, planning, and the relational constructs that Milvus intentionally does not try to become a full relational database for. |
|
@xiaofan-luan — thank you for taking the time on this personally; I didn't expect the project lead to work through four questions in that much detail. Taking your closing boundary as the design principle: push single-collection filtering, sorting, aggregation, grouping and vector search into Milvus wherever Milvus has native semantics, and keep the SQL layer on compatibility, planning, and the relational constructs Milvus deliberately isn't becoming. That is a sharper statement of scope than I had written for myself, and it's going into the README as the stated design goal. Four things change concretely on my side: Dialect alignment toward PostgreSQL. Point 3 is the one that reshapes the project. My vector syntax is already pgvector-shaped ( The ID-set pattern gets its own seam. Query one collection for a key set, filter another by it — that's exactly what my planner does for equi-joins today, so that's the piece going behind a replaceable interface, since it's the most likely to get a native equivalent. Knowing that general complex joins are out of scope is equally useful: it makes the client-side reduction a permanent part of the design rather than a placeholder. Grouping Search instead of facets for top-k-per-group. You're right that facets answer a different question. Recognising
You already answered the question I was most nervous about — whether a SQL layer has a useful role at all — so I won't re-ask it. Three narrower things, and please treat all of them as no-obligation:
Thanks again. This saved me a substantial amount of work in the wrong direction. |
|
@Neko1313 @yhmo @xiaofan-luan @augustocbx Here’s a tool that lets you interact with Milvus using SQL through a JDBC driver. It supports common statements such as INSERT, UPDATE, DELETE, and SELECT, along with data import and many administrative operations. It looks like it could already serve as an alternative to the SDK. https://www.dbvisitor.net/en/docs/features/milvus/about |
Wire compatibility (your prerequisite question).
The 2.6 client line does work against a 3.0 server — the protocol evolves additively, so existing 2.6 interfaces continue to work as-is. What you cannot do from the 2.6 client is reach the new 3.0 capabilities: the first-class TEXT type, in-kernel GROUP BY/ORDER BY/aggregates, SearchAggregation, native cursor iteration (SearchIteratorV2Info/QueryIteratorCursor). So 3.0 support is not an all-or-nothing port — it's a progressive migration: your existing 2.6 SQL layer keeps working unchanged, and you adopt the 3.x client only when (and where) you want to unlock the new server-side features. That's a comfortable position: nothing forces the s…